我有一个非常连贯的错误,我的一个自定义控件似乎创建了两个编译文件,当我尝试使用 LoadControl()
动态加载它时只是失败,因为不能将一个转换为另一个 - 即使它们完全相同。我写的帖子看,都是一样的,只是修改了编译的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'.
编码
这是我关注后的代码 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
}
以前我在没有
ASP.
的情况下加载控件但是在出现此错误并寻找解决方案后,我严格遵循 MSDN 上的内容。无论我做什么,错误仍然存在。我也尝试过这两种方法,一种是单独的,一种是一起尝试的(再次失败)
<%@ Register src="~/mod/OneProduct_MediumImage.ascx" tagname="OneProduct_MediumImage" tagprefix="uc1" %>
<%@ Reference Control="~/mod/OneProduct_MediumImage.ascx" %>
配置
我的 web.config,我已经尝试使用
maxBatchSize
20、100、1000,还有 optimizeCompilations
true 或 false,但错误再次出现。<compilation debug="false" defaultLanguage="C#" batch="true"
maxBatchSize="800" batchTimeout="10800" optimizeCompilations="false"
targetFramework="4.0">
现在有关的一些细节
optimizeCompilations
真假,同样的问题。 batch="true"
在 web.config 上,错误立即出现。 当这个错误出现时,我现在做的解决方法是:我只是强制项目以小的更改重新编译,错误消失,直到下一次更新。
我有一个错误,试图在没有找到原因的情况下解决最后一个树周。我已经尝试了几乎所有我能做的事情,但都失败了,并且错误再次出现。所以我在这里发布也许有些人可以帮助我并找到解决方法。
最后一句话:这个错误很疯狂,自定义控件是一样的,我对它做任何事情我只动态加载它并且繁荣,编译器由于某种只有他知道的原因有两次不同的时间 - 随机。
更新 1
我能够在开发人员机器上重现该错误。在那里我发现包含这个自定义控件的两个 dll 模块有一个不同的。
一个是捆绑在一起的 4 个自定义控件。另一个模块是单独的自定义控件。
解决方法
经过数周尝试修复此错误后,我最终发现当编译器对目录进行批处理编译并在同一个 dll 中捆绑许多不同的自定义控件时,会出现此错误。所以当我尝试单独加载它时会抛出这个异常。
因此,我将有问题的自定义控件单独移到了不同的目录中,并且似乎暂时避免使用它。
更新 2
再次出现,即使在我将一些文件移动到不同的目录之后。是随机的,无法找到与触发其的明确联系。
更新 3
因为我们发现这里的主要问题是批量编译(
batch="true"
)在同一个 dll 上编译许多自定义控件,告诉编译器不要这样做的一种方法是 maxBatchGeneratedFileSize
范围。我使用它的值为 100,问题再次出现,现在我将其降低到 40 并进行测试。maxBatchGeneratedFileSize="40"
最佳答案
当您打开批处理并在目录级别具有某种形式的循环引用时,就会发生这种情况。
请看这个answer确切地了解我在这种情况下所说的“循环引用”是什么意思,因为其含义非常微妙。
如果您设法打破循环(例如通过将用户控件移到别处),您将不会遇到此问题。
更新 1
我认为理论上,这只能由一个循环引起,但有时它们很难检测到。
我会给你一个我认为可行并且很容易尝试的替代解决方案(即使它有点黑客)。在给您带来问题的用户控件中,在指令中添加以下属性:
<%@ Control Language="C#" [...] CompilerOptions="/define:dummy1" %>
如果您在其他一些控件中看到这一点,您可以添加相同的内容,但使用 dummy2、dummy3 等...
这将不会对这个用户控件进行批处理,因为它与其他用户控件有不同的编译需求。从技术上讲,您可以添加任何 C# 命令行作为
CompilerOptions
,但是一个假人 /define
是最简单也是最无害的。但与全局关闭批处理不同,性能影响将是最小的,因为只有非常小的页面子集不会被批处理。
顺便说一句,不用说,您所看到的是 ASP.NET 中的一个错误,并且该错误可能已经存在 10 多年了!也许在某个时候它应该得到解决:)
关于c# - 相同类型对象的 InvalidCastException - 自定义控件加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14796546/