Unable to cast object of type 'ASP.masterpage_master' to type 'ASP.masterpage_master'.
If you ever come across this error you can you can usually resolve it pretty quickly, but most likely it will crop up again. The InvalidCastException, “Unable to cast object of type ‘ASP.type’ to ‘ASP.Type’” is an extremely random occurring error. It is so difficult to pinpoint that even Microsoft’s crack programmers only have an unpublished HotFix available. You need to call to get the HotFix. There seem to be some common ways to correct this error, but none are reasonable for many situations.
According to the KnowledgeBase article there are four scenarios this can occur, mine was caused by issue #2.
- The Web application uses a master page, a user control, or pages that reference each other.
- The master page, the user control, or the pages are batch compiled into a single assembly.
- One of the batched dependencies is changed and causes a recompilation.
- A dynamic call to load a reference is made, such as a call to the LoadControl method.
First what is this error and how do you get it. Well I am not completely sure how to ‘get’ the error; I only know it randomly occurs in ASP.NET nature (take that Discovery channel). Anyway, I seem to occasionally get this error where I am using a MasterPage that is inherited from a custom MasterPage class I created that inherits directly from MasterPage itself. So if you look at the hierarchy you would see MasterPage -> MyBaseMasterPage -> MyActualMasterPage. The error would look like:
Unable to cast object of type 'ASP.MyActualMasterPage ' to type 'MyActualMasterPage'
An example of the code that will cause this error would look like the following:
‘This is where the error would be indicated
99.99% of the time you will never see this error occur. But if you do there seems to be an order to which you need to take to combat the problem. The worse solution is to break your architecture and replicate common code into the class for each MasterPage class you create, please do not do this or someone may report you to WorseThanFailure.com one day. The first step is to modify your web.config file to turn Batch Compilation off. To do this locate the compilation tag in your web.config file and set batch=”false”.
<compilation defaultLanguage="vb" debug="true" batch="false">
The batch attribute indicates if batch compiling is turned on, here is the definition of the attribute according to the documentation:
If True, eliminates the delay caused by the compilation required when you access a file for the first time. When this attribute is set to True, ASP.NET precompiles all the uncompiled files in a batch mode, which causes an even longer delay the first time the files are compiled. However, after this initial delay, the compilation delay is eliminated on subsequent access of the file.
The reason you would want to turn the batch compiler off is because this is where the bug resides. So by turning the batch compiler off you are bypassing the problem, but you may be creating a slight performance hit. I found that this solved my problem on the development server setup, but not on the production setup.
The next step is to contact Microsoft Support through the Knowledgebase article about the HotFix. I did this and even got a second HotFix after the first one did not work. We did not get a chance to apply the second HotFix to the production server because I solved the problem for us right before this came in.
Before I get to the way I have ultimately solved the problem, I want to offer some more hints as to what I experienced. First there seems to be a symptom this might be an issue inside of Visual Studio. From time to time my references to my MasterPage classes are marked as an error or that the class does not exists. I found a way to eliminate the falsely reported error and that was to close Visual Studio and clear the temporary files associated with the web site on my workstation. These files are located in the C:\%SystemDir%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files” directory. You will see a subdirectory for each web site you have worked on since you last cleaned the structure. I generally delete every folder in this directory and start fresh.
Another odd behavior I noticed was right-clicking the MasterPage class causing the error and choosing to go to the Definition took me to the Class Viewer and a reference to an object in the above mentioned temp directory. I have not clue as to what causes this behavior, the class definitely exists.
This is another very strange issue in recreating the error. I could visit the site from my workstation and load various pages over and over for a long period of time. In fact I actually ran an automated script for about an hour at one point with no errors generated whatsoever. I could then open a new browser and suddenly the casting error would rear its ugly head. Since I am not privileged enough to know how the ASP.NET engine really runs at the metal, I have no clue as to why I generated what I did.
The last symptom is that it seems the error will magically correct itself after a minute or two and is not consistent between pages either. For example if I can load a few pages that use MyMasterPage and they all have the same code to cast a reference to the MyMasterPageClass without causing the error. I may get to the fourth page and the error is thrown. I can go back to other pages that use that class and have the line and they work fine. Then I can go back to the page that threw the error and it may or not be there again, typically I think if I gave it a minute or so, the error would go away. It is tough to say this will happen in every situation. My setup involved a four server web farm, so I may have just been routed to a new server that did not cause the error.
Now to how I have ultimate solved my problem. I just happened to have found some good articles about pre-compiling ASP.NET 2.0 applications a few days before these errors hit. Since the errors seem to be caused by the batch compiler I thought it might be worth a shot to pre-compile the site so the batch compiler would be bypassed altogether. It worked and we are now able to proceed. I plan on dropping another entry on pre-compiling altogether because I think this may be one of the best options an ASP.NET team has for an extremely high performance application too.