Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InvalidCastException for Object of the same type - Custom Control Load

I have a very wired error, one of my custom controls seems that is create two compiled files, and when I try to load it dynamically with LoadControl() is just fail because can not cast the one to the other - even if they are exactly the same. I write the message to see that all is the same, is only change the compiled dll.

System.Web.HttpUnhandledException (0x80004005):       Exception of type 'System.Web.HttpUnhandledException' was thrown. --->                  System.InvalidCastException: [A]ASP.Modules_OneProduct_MedioumImage cannot be cast to [B]ASP.Modules_OneProduct_MedioumImage.              Type A originates from 'App_Web_kg4bazz1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default'     at location 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\80ed7513\10eb08d9\App_Web_kg4bazz1.dll'.               Type B originates from 'App_Web_oneproduct_mediumimage.ascx.d1003923.4xoxco7b, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'  in the context 'Default'         at location 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\80ed7513\10eb08d9\App_Web_oneproduct_mediumimage.ascx.d1003923.4xoxco7b.dll'. 

The code

This is the code as it is right now after I have follow exactly what is written on MSDN:

foreach (int OneProductID in TheProductIdArrays) {     // here is the throw.     ASP.Modules_OneProduct_MedioumImage OneProduct =          (ASP.Modules_OneProduct_MedioumImage)LoadControl(@"~/mod/OneProduct_MediumImage.ascx");      // do some work with      //OneProduct } 

Previously I have Load the control without the ASP. but after this bug appears and looking for solution, I strictly follow what is on MSDN. The bug is still here no matter what I do.

I have also try both of this methods, each one alone, and together (again fail)

<%@ Register src="~/mod/OneProduct_MediumImage.ascx" tagname="OneProduct_MediumImage" tagprefix="uc1" %> <%@ Reference Control="~/mod/OneProduct_MediumImage.ascx" %> 

Config

My web.config, I have try with maxBatchSize 20, 100, 1000, also with optimizeCompilations true or false, but the bug is appears again.

<compilation debug="false" defaultLanguage="C#" batch="true" maxBatchSize="800" batchTimeout="10800" optimizeCompilations="false" targetFramework="4.0"> 

Now some details about

  • The error is random, in some compile appears, in some other not.
  • The project is a big one, the pages are live with a lot of people in every minute that ask to see something, but also appears when there is no one inside.
  • Is run on 64bit dot.net 4, Intergrated
  • Run as web garden but also tested and one pool alone (and get the same issue)
  • The session is off on the full project.
  • The pages are run from 2007 but this issue is appears the last month, unfortunately I can not find where and how is started, or what is trigger it because I late some days to see it.
  • Appears only one one custom control loads, the one that have heavy call.
  • I have change 4 times the code making small changes, or big changes and still there.
  • I have try with optimizeCompilations true and false and the same issue.
  • I have try also by stopping the web, delete all temporary files, reopening, and there was again.
  • I have try to place a mutex on global.asax when the application starts to lock only one compile at the time, but this fails also.
  • From the moment that works, then all is good, but if not works is not auto corrected.
  • The code that I load this custom control is exist and called in more than one places on the code, on different pages.
  • Other custom controls, with similar load did not have any problems.
  • ViewState is disabled for this custom control.
  • I have also try relocate some code, change the full function call with micro optimizes, no again fail.
  • Is work fine on development computer. I place batch="true" on web.config and the bug appears right away.
  • There are no other issues like that, like a bug that we can not fix no matter what. The system is run for days, the pool is NOT recycle at all, the memory is stable, and there is more free to use. The program is run for years now, but we change is almost every day with updates.
  • Under the same core code runs more than one sites (something like stackexchange) and all have the same random problem.
  • The AutoEventWireup is false
  • Its appears and on other custom control that I load the same way.

What I do now as workaround when this bug appears: I just force the project to recompile with a small change, and the error go away, until the next update.

I have a bug that try to solve the last tree weeks with out find the reason. I have try almost anything I can thing of, but all fails, and the bug appears again. So I post here maybe some can help me out and find a way out of this.

Last word: This bug is crazy, the custom control is the same, I do anything on it I only load it dynamically and boom, the compiler is have it two different times for some reason that only he knows - randomly.

Update 1

I been able to reproduce the bug on the developer machine. There I discover that the two dll modules that contains this custom control have a different.

The one was a bundle of 4 custom controls together. The other module was the custom control alone.

Workaround

After tree weeks trying to fix this bug I end up that this bug is appears when the compiler make batch compile of a directory, and bundle many different custom controls, in the same dll. So when I try to load it alone is throw this exception.

So I move the problematic custom control in a different directory alone and seems that I avoid it for now.

Update 2

Appears again, even after I move some files to a different directory. Is random and can not find a clear connection with what is triggers its.

Update 3

Because we have spot that the main issue here is the batch compile (batch="true") that compiles on the same dll many custom controls, one way to say to the compiler to NOT do that, is the maxBatchGeneratedFileSize parameter. I use it with a value of 100, and the issue appears again, now I have lower it to 40 and test it.

maxBatchGeneratedFileSize="40" 
like image 622
Aristos Avatar asked Feb 10 '13 10:02

Aristos


1 Answers

This can happen when you have batching turned on and have some form of circular references at the directory level.

Please see this answer to see exactly what I mean by 'circular references' in this context, as the meaning is quite subtle.

If you manage to break the cycle (e.g. by moving a user control elsewhere), you will not hit this issue.

Update 1

I would think that in theory, this can only be caused by a cycle, but sometimes they can be hard to detect.

I'll give you an alternative solution which I think will work and is very easy to try (even though it is a bit of a hack). In the user control(s) that is giving you problems, add the following attribute in the directive:

<%@ Control Language="C#" [...] CompilerOptions="/define:dummy1" %> 

If you see this with some other controls, you can add the same thing but with dummy2, dummy3, etc...

This will have the effect of not batching this one user control, since it has different compilation needs from the others. Technically, you can add any piece of C# command line as the CompilerOptions, but a dummy /define is the simplest and most harmless.

But unlike turning off batching globally, the perf impact will be minimal, since only a very small subset of pages will not be batched.

BTW, it goes without saying that what you're seeing is a bug in ASP.NET, and that bug has been there for probably 10+ years! Maybe at some point it should get addressed :)

like image 105
David Ebbo Avatar answered Oct 07 '22 12:10

David Ebbo