Category Archives: code

Remote Desktop when all Terminal Services Connections are in Use

This comes up more often than we’d like. And while I’d love Microsoft to fix this and allow unlimited Remote Desktop connections to a server, it doesn’t seem like it’s going to happen. If you get the dreaded “The terminal server has exceeded the maximum number of allowed connections” message, here’s how you can force connect and boot someone else:

Mstsc /v:192.168.0.x /admin /F

It used to be /console instead of /admin, but that went away in XP SP3.

But let’s be clear on what the real fix here is: Microsoft needs to release the 2-user limit on administrator connections for servers that are never going to be used as interactive applications servers. If I’m setting up a new web server or SQL server, there’s no reason I shouldn’t be able to have three or five or 10 administrators logged in at once.

Invalid Viewstate errors in ScriptResource.axd and WebResource.axd

I’ve done the requisite google searching on this one and can’t find a solution, so I’m posting about it in case anyone has an answer…

The basic problem is, I have an ASP.NET Dynamic Data web site that is experiencing occassional “Invalid viewstate errors” in the ScriptResource.axd or WebResource.axd javascript includes on the page. In almost all cases these are due to the URL of the include being corrupted with HTML or other text from the page. That is, instead of the normal “d” and “t” parameters in the querystring, I see something like this (as reported by my custom error handler in global.asax, which emails me a report for every Application_Error event):

http://domain-omitted/ScriptResource.axd?d=w0PmGeT7CMNAKpp-4k5pBNkf0bD1315QQFyhtn4142pWyyhkp5lhqQR6XcoT1lgNSX5Cdw8Q6uPcgDBOu4CSX-e3-cB38lN5S211HGUect<span class=

Querystring:
d=w0PmGeT7CMNAKpp-4k5pBNkf0bD1315QQFyhtn4142pWyyhkp5lhqQR6XcoT1lgNSX5Cdw8Q6uPcgDBOu4CSX-e3-cB38lN5S211HGUect%3cspan+class%3d

I have not been able to replicate this in testing, but in the field, where we have the application running exclusively on IE8 clients, we are seeing this behavior. I’ve read that this could have something to do with IE8’s parsing engine (Trident/4.0). I’ve validated my page using w3c (document type: XHTML 1.0 Transitional). There are a couple of attribute validations I can’t solve, but they’re for stuff like border=”0″ in something generated by the .NET platform (which isn’t actually sending border=”0″ but rather ‘style=”border-width:0px;”‘ as part of an asp:Button… more weirdness). I’ve made sure that all my local javascript is enclosed in XML data blocks as was suggested by some of the forum posts on this topic.

Server is up to date with Windows Server 2003 Standard x64, .NET Framework 3.5 SP1 with family updates installed.

Anyone have any further suggestions?

Can I Has Layout?

Just got bitten by the IE7 (or IE8 “compatability view”) has layout bug yet again, so posting it…

Basically, in the IE7/IE8cv you can only check .clientHeight on elements where hasLayout==true. If your clientHeight is always returning 0, chances are you don’t have layout. The easiest way to get layout? Set display=”inline-block”. Per:

http://bytes.com/groups/javascript/564442-ie-clientheight-problem

And that article points to this one, which is pretty much the definitive source (top Google hit!):

http://www.satzansatz.de/cssd/onhavinglayout.html

height:1% is what I ended up using to make a resizable div “hasLayout.”

display: inline-block makes the div not size to the window horizontally, which didn’t work for my purpose.

I tried using overflow:hidden, but that doesn’t help in IE6.

Stored Procedure to Generate INSERT Statements for All Table Rows Under SQL Server 2005

If you need to create a “data dump” for Microsoft SQL Server, here’s a good free tool:

http://vyaskn.tripod.com/code.htm#inserts

The one thing I haven’t gotten working is any way to automatically add the “SET INDENTITY_INSERT ON/OFF” statements bracketing a table which contains an identity when not using the @ommit_identity = 1 switch. It might be in the comments, I just didn’t dig through it.

I’ll attach them in case that page ever goes away.

SQL 2000 Version

SQL 2005 Version

80/18/2

I’ve come up with a new 80/20 rule for working with Microsoft development products (but it may be universal):

  • The first 80% is easy, if not already done for you.
  • The second 18% is hard, often requiring an undocumented set of hacks to accomplish.
  • The last 2% is impossible.

In my experience, somewhere around 83% you hit diminishing returns. At 97% you’re bleeding from the eyes.

Copy a SQL Record with LINQ Using Object Shallow Copy

I wish I had kept my reference material on this, so if anyone recognizes borrowed code here, please let me know…

The basic idea is, I needed to “copy” a SQL record within the same table, avoiding some fields. With SQL this could be accomplished with something like:

INSERT INTO ShippingInfo (Name,Value) SELECT Name,Value FROM ShippingInfo where id=5

But imagine there are 20 fields or so. I couldn’t find a native way to do this with LINQ. What I came up with is an object shallow copy with the ability to punch out (omit) fields by name. Here’s the method:

public static class AnyObject<t> where T : class, new()
{
    public static T ShallowCopy(T item)
    {
        return ShallowCopy(item, "");
    }
    
    public static T ShallowCopy(T item, string OmitPropeties)
    {
        if (item == null)
        {
            return null;
        }
        T newItem = new T();
        foreach (System.Reflection.PropertyInfo prop in item.GetType().GetProperties())
        {
            if ((prop.PropertyType.IsValueType || prop.PropertyType.Name == "String") && 
                !prop.PropertyType.Name.StartsWith("EntitySet") &&
                !("|"+OmitPropeties+"|").ToLower().Contains("|"+prop.Name.ToLower()+"|"))
            {
                System.Reflection.PropertyInfo prop2 = item.GetType().GetProperty(prop.Name);
                prop2.SetValue(newItem, prop.GetValue(item, null), null);
            }
        }
        return newItem;
    }
}

Then you call it like…

// get the source record
ShippingInfo TempShipping;
TempShipping = (from s in db.ShippingInfos 
          where s.Id == tempShippingId select s).FirstOrDefault();

// shallow copy the object
ShippingInfo NewShipping = Helpers.AnyObject<shippinginfo>.ShallowCopy(TempShipping, 
                                              "Id|ModifiedBy|ModifiedTime");

// override some copied fields
NewShipping.CreatedBy = PageContext.UserId;
NewShipping.CreatedTime = DateTime.Now;

// insert it
db.ShippingInfos.InsertOnSubmit(NewShipping);
db.SubmitChanges();

Bitwise AND for Large Numbers in Traditional ASP

Once in a while (like today) I have to go back and do something in traditional ASP (Active Server Pages). That’s when I realize how nice .NET is, with typed data and all those framework methods. Something seemingly trivial, like figuring out if an IP address is part of a network, turns out to be quite difficult. The normal approach here would be to convert the IP address, network and subnet into integers, do a bitwise AND of the two items, and then compare the result. Unfortunately, the “AND” operator in ASP only works with integers and “Long” integers (up to 2^31 or 2,147,483,647), and the integer representation of 255.255.255.0 is 4,294,901,760. Uh oh. So, I came up with a double-precision AND function which splits the double value into “high” and “low” chunks (basically, the part below 2^31 and the part above), performs a bitwise AND on the chunks, and then shifts the bits back into place and reassembles a Double value from this. This should be viable for the bits left of the decimal up to about 4.6E+18. At the very least, it’s working for the IP address example.

function DoubleAnd (d1,d2)
    ' bitwise AND for values potentially greater than the Long limit (2147483647)
    dim d1low, d1high, d2low, d2high, lowand, highand
    d1high = fix(d1 / (2^31))
    d1low = fix(d1 - d1high * (2^31))
    d2high = fix(d2 / (2^31))
    d2low = fix(d2 - d2high * (2^31))
    lowand = d1low and d2low
    highand = d1high and d2high
    DoubleAnd = highand * (2^31) + lowand
end function

It’s called like this:

if (DoubleAnd(ipint,subnetint)) = (DoubleAnd(networkint,subnetint)) then
    response.write ("IP is on network")
else
    response.Write ("IP is NOT on network")
end if

Note that I’m ANDing both the ip address and the network address. This shouldn’t technically be necessary, but it helps in cases where the user types in another IP address on the network instead of the network address (e.g. 192.168.1.1 instead of 192.168.1.0).

Here are the helper functions required for the conversions:

function IsValidIpAddress (IP)
    dim aGroups, i, j
    aGroups = split(IP,".")
    if ubound(aGroups) <> 3 then
        IsValidIpAddress = false
        exit function
    end if
    for i = 0 to ubound(aGroups)
        j = aGroups(i)
        if not isNumeric (j) then
            IsValidIpAddress = false
            exit function
        end if
        if j < 0 or j > 255 then
            IsValidIpAddress = false
            exit function
        end if
    next
    IsValidIpAddress = true
end function
function IntegerFromIPAddress (IP)
    if (IsValidIpAddress(IP)) then
        dim aGroups
        aGroups = split(IP,".")
        IntegerFromIPAddress = aGroups(3) + aGroups(2) * 256 + aGroups(1) * 256^2 + aGroups(0) * 256^3  
        exit function
    else
        IntegerFromIPAddress = -1
    end if
end function

Note, all these function assume IPv4. Yes, there’s a potential Y2K-style problem lurking here, but I just can’t deal with the absurdity of making a traditional ASP application IPv6-aware at the moment.

Returning a Strongly-Type IEnumerable from a SQL Stored Procedure Using LINQ to SQL

This is surprisingly difficult, but there’s a relatively robust way to do it:

Create your stored procedure
Create a view that mimics the return signature of the stored procedure
In the model (.dbml), import both the stored procedure and view
Set the “Return Type” property of the stored procedure Data Function to the view type
In code, use the .ToList() method of the stored procedure function of the model and cast it to an IEnumerable of the view type, for example:

DBDataContext db = new DBDataContext();
IEnumerable<vwUspEventCalendarResultSet> CalendarResults = db.uspEventCalendar(CustomerId, StartDate, EndDate, DataStartDate, DataEndDate).ToList();

One thing to be careful of is if your stored procedure might return null values in integer key columns you may have to ISNULL them to 0 or some other meaningful value (in the stored procedure) since LINQ to SQL does not pick up a nullable int type from the view signature.

Here are the code bits to back this up…

View:

SELECT     dbo.AllDates.TheDate, dbo.Events.Id, dbo.Events.Name, dbo.Events.Description, dbo.Events.Url, dbo.Events.CustomerId, dbo.Events.TeamId, 
                      dbo.Events.ShowCityId, dbo.Events.EventStartDate, dbo.Events.EventEndDate, dbo.Events.EventMoveInDate, dbo.Events.EventMoveOutDate, 
                      dbo.Events.EventAddressId, dbo.Events.InventoryPullDate, dbo.Events.InventoryShipDate, dbo.Events.InventoryReturnDate, 
                      dbo.Events.InventoryAvailableDate, dbo.Events.EventShippingInfoId, dbo.Events.EventReturnAddressId, dbo.Events.EventAttendance, 
                      dbo.Events.BoothNumber, dbo.Events.BoothSize, dbo.Events.CeilingHeight, dbo.Events.BoothAttendance, dbo.Events.LeadsCaptured, 
                      dbo.Events.CreatedBy, dbo.Events.CreatedTime, dbo.Events.ModifiedBy, dbo.Events.ModifiedTime, dbo.Events.Deleted, dbo.Events.Active, 
                      dbo.Events.Notes
FROM         dbo.Events INNER JOIN
                      dbo.AllDates ON dbo.Events.EventStartDate = dbo.AllDates.TheDate

Stored Procedure:

ALTER PROCEDURE [dbo].[uspEventCalendar] 
	-- Add the parameters for the stored procedure here
	@CustomerId int = 0, 
	@StartDate datetime = null,
	@EndDate datetime = null,
	@DataStartDate datetime = null,
	@DataEndDate datetime = null
AS
BEGIN
	-- default to "this month"
	if @StartDate is null 
		SET @StartDate = cast(cast(DatePart(month,getdate()) as varchar) + '/1/' + cast (DatePart(year,getdate()) as varchar) as datetime)
	if @EndDate is null 
		SET @EndDate = dateadd(day,-1,dateadd(month,1,@StartDate))
	if @DataStartDate is null 
		SET @DataStartDate = @StartDate
	if @DataEndDate is null 
		SET @DataEndDate = @StartDate

	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	--SET NOCOUNT ON;
	--SELECT @StartDate,@EndDate
    -- Insert statements for procedure here
	
	SELECT CalendarDates.TheDate,
					ISNULL(EventCalendarEntries.Id,0) as Id, EventCalendarEntries.Name, EventCalendarEntries.Description, EventCalendarEntries.Url, EventCalendarEntries.CustomerId, 
                      EventCalendarEntries.TeamId, EventCalendarEntries.ShowCityId, EventCalendarEntries.EventStartDate, EventCalendarEntries.EventEndDate, EventCalendarEntries.EventMoveInDate, 
                      EventCalendarEntries.EventMoveOutDate, EventCalendarEntries.EventAddressId, EventCalendarEntries.InventoryPullDate, EventCalendarEntries.InventoryShipDate, 
                      EventCalendarEntries.InventoryReturnDate, EventCalendarEntries.InventoryAvailableDate, EventCalendarEntries.EventShippingInfoId, 
                      EventCalendarEntries.EventReturnAddressId, EventCalendarEntries.EventAttendance, EventCalendarEntries.BoothNumber, EventCalendarEntries.BoothSize, 
                      EventCalendarEntries.CeilingHeight, EventCalendarEntries.BoothAttendance, EventCalendarEntries.LeadsCaptured, EventCalendarEntries.CreatedBy, 
                      EventCalendarEntries.CreatedTime, EventCalendarEntries.ModifiedBy, EventCalendarEntries.ModifiedTime, EventCalendarEntries.Deleted, EventCalendarEntries.Active, 
                      EventCalendarEntries.Notes
		 FROM 
		(SELECT thedate from alldates where thedate BETWEEN @StartDate AND @EndDate) as CalendarDates LEFT OUTER JOIN
		(SELECT     EventDates.TheDate, EventsInRange.Id, EventsInRange.Name, EventsInRange.Description, EventsInRange.Url, EventsInRange.CustomerId, 
                      EventsInRange.TeamId, EventsInRange.ShowCityId, EventsInRange.EventStartDate, EventsInRange.EventEndDate, EventsInRange.EventMoveInDate, 
                      EventsInRange.EventMoveOutDate, EventsInRange.EventAddressId, EventsInRange.InventoryPullDate, EventsInRange.InventoryShipDate, 
                      EventsInRange.InventoryReturnDate, EventsInRange.InventoryAvailableDate, EventsInRange.EventShippingInfoId, 
                      EventsInRange.EventReturnAddressId, EventsInRange.EventAttendance, EventsInRange.BoothNumber, EventsInRange.BoothSize, 
                      EventsInRange.CeilingHeight, EventsInRange.BoothAttendance, EventsInRange.LeadsCaptured, EventsInRange.CreatedBy, 
                      EventsInRange.CreatedTime, EventsInRange.ModifiedBy, EventsInRange.ModifiedTime, EventsInRange.Deleted, EventsInRange.Active, 
                      EventsInRange.Notes
FROM         (SELECT     Id, Name, Description, Url, CustomerId, TeamId, ShowCityId, EventStartDate, EventEndDate, EventMoveInDate, EventMoveOutDate, 
                                              EventAddressId, InventoryPullDate, InventoryShipDate, InventoryReturnDate, InventoryAvailableDate, EventShippingInfoId, 
                                              EventReturnAddressId, EventAttendance, BoothNumber, BoothSize, CeilingHeight, BoothAttendance, LeadsCaptured, CreatedBy, 
                                              CreatedTime, ModifiedBy, ModifiedTime, Deleted, Active, Notes
                       FROM          Events
                       WHERE      (EventStartDate < = @DataEndDate) AND (EventEndDate >= @DataStartDate)) AS EventsInRange CROSS JOIN
                          (SELECT     TheDate
                            FROM          AllDates
                            WHERE      (TheDate BETWEEN @StartDate AND @EndDate)) AS EventDates
WHERE     (EventDates.TheDate BETWEEN EventsInRange.EventStartDate AND EventsInRange.EventEndDate)) EventCalendarEntries ON EventCalendarEntries.thedate = CalendarDates.thedate
END

Insert a Record for Every Date Between Two Dates

Revisiting the Common Table Expression from an earlier post, I had already forgotten how to do this thing I actually ended up using this for, which was populating an “AllDates” table for my database. It turned out to be a lot easier to do this and then JOIN to it than to incorporate the CTE code into a larger query. So, here’s how to turn the CTE from the earlier post into an insert statement:

GO
/****** Object: Table [dbo].[allDates] Script Date: 03/27/2008 13:34:54 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[allDates](
[thedate] [datetime] NOT NULL,
CONSTRAINT [PK_allDates] PRIMARY KEY CLUSTERED
(
[thedate] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

WITH datecte(anydate) AS (SELECT CAST(‘1/1/2000’ AS datetime) AS anydate
UNION ALL
SELECT anydate + 1 AS anydate
FROM datecte AS datecte_1
WHERE (anydate < CAST('1/1/2021' AS datetime) - 1)) INSERT INTO allDates SELECT anydate FROM datecte AS datecte_2 OPTION (MAXRECURSION 10000)