Mark Gilbert's Blog

Science and technology, served light and fluffy.

Unable to cast object of type ‘Haystack.Needle’ to ‘Haystack.Needle’ – Temporary ASP.NET Files

About twice a year, it seems, I come up against a terribly clever error message:

InvalidCastException: Unable to cast object of type ‘X’ to ‘X’

Where “X” is some type in my ASP.NET web application.  Wait, why are you trying to cast an object to its own type, and why didn’t it work?!?

There are other ways that that this error can manifest (such as trying to dynamically load a DLL), but with an ASP.NET web application the issue always seems to boil down to the contents of the %windir%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files folder (I’ll refer to this as the “temp” folder).

When you deploy a .NET web application, your site’s files and binaries are copied to a temporary folder, where they are (I believe) ultimately executed.  This allows you to deploy updates to the site without having to stop and restart the site in IIS (IIS locks the “temporary” copies of the files, not the ones you drop into the web root).  Then, .NET will watch your site’s folder and re-caches the files them when they change.

This process works well the vast majority of the time.  Every now and then, however, the files get out of sync.  For reasons that continue to elude me, sometimes .NET doesn’t properly update the temp folder.  Then, when it goes to execute the logic in the DLL, the signatures of the copy in /bin and the copy in the temp folder don’t match.  Even if your object type in both of these is identical, .NET will still treat these as different assemblies – different types – hence, “Unable to cast object of type ‘X’ to ‘X’”.  So, to get these back into sync, we need to force the temp files to be updated.  Sounds simple, right?

Since “twice a year” came due this past week, let’s run through what I tried before I finally got the files synced back up:

1) Stop and restart the app domain that the site was running in.

2) Make a change to the web.config for the site.

3) Stop and restart the site in IIS.

I thought that any of these should have caused the temp files to be rebuilt, but none of them did the trick this time.  I could have sworn that one of these worked for me in the past, so either A) I’m losing my mind, or B) this week’s occurrence was somehow different.  Smart money’s on “A”.

So, on to the more destructive solutions.  The most destructive one that I found when researching this online was to stop and restart all of IIS – literally killing the service and bringing it back up.  Since this was one of dozens of sites running on the server, that seemed like the nuclear option to me – I wanted something more surgical.

The temp folder has subfolders for each site and virtual directory managed by the web server.  For the latter, there are folders named after the app, so http:\\MyDomain.com\CoolApp would have its cached files in %windir%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET File\CoolApp.

If you have multiple web sites on the server, however, they don’t get nicely-named subfolders.  On my server, all of the web sites were placed as subfolders of %windir%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET File\root.  To further complicate things, the folders there were not named after the corresponding sites – they were randomly assigned alphanumeric names – 7cc91a62, 307e26d7, and so on.  And if that wasn’t bad enough, there doesn’t seem to be direct way to figure out which folder goes with which site (a read-only field in the IIS properties dialog for the site would have been splendid).  So, now I’m reduced to searching through dozens of folders below “root” to find the right one.

The DLLs aren’t the only thing that get cached here – the ASPX files are also copied in.  So, the solution that I settled on (and the one that finally worked) was to search “root” and all of its contents for a file that only existed in the site having the problems.  I could not search for “BeautifulAndUniqueSnowflake.aspx” however – I had to search for “BeautifulAndUniqueSnowflake.aspx.*” since the files get extra stuff tacked on the end.

Once I found the right folder, I stopped the site in IIS, deleted the folder below “root” that contained BeautifulAndUniqueSnowflake.aspx.*, and restarted the site.  I watch the “root” folder to make sure a new subfolder was created when I visited the site – confirmation that what I was doing was actually having an effect.  Once the files were re-cached from scratch, the error went away.

 

Special thanks to Joel and Ron for helping troubleshoot this issue, and craft the final solution.

Advertisements

November 8, 2010 - Posted by | Visual Studio/.NET

Sorry, the comment form is closed at this time.

%d bloggers like this: