我有一个非常有线的错误,我的一个自定义控件似乎是创建了两个编译文件,当我尝试使用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上的内容进行操作。无论我做什么,这个bug仍然在这里。
我也尝试了这两种方法,每种方法都在一起,并且一起(再次失败)
<%@ Register src="~/mod/OneProduct_MediumImage.ascx" tagname="OneProduct_MediumImage" tagprefix="uc1" %>
<%@ Reference Control="~/mod/OneProduct_MediumImage.ascx" %>
我的web.config,我尝试使用maxBatchSize
20,100,1000,同时optimizeCompilations
为真或假,但错误再次出现。
<compilation debug="false" defaultLanguage="C#" batch="true"
maxBatchSize="800" batchTimeout="10800" optimizeCompilations="false"
targetFramework="4.0">
optimizeCompilations
true和false以及相同的问题。batch="true"
放在web.config上,然后就会出现错误。当我出现此错误时,我现在所做的是解决方法:我只是强制项目通过一个小的更改重新编译,错误消失,直到下一次更新。
我有一个错误,尝试解决最后一个树周,找出原因。我几乎尝试了任何我能做到的事情,但都失败了,而且这个bug又出现了。所以我在这里发帖也许有些人可以帮我解决这个问题。
最后一句话:这个错误很疯狂,自定义控件是一样的,我对它做了什么我只是动态加载它并且繁荣,编译器有两个不同的时间由于某种原因只有他知道 - 随机。 / p>
我能够在开发者机器上重现该错误。在那里我发现包含这个自定义控件的两个dll模块有不同的。
一个是一组4个自定义控件。另一个模块是单独的自定义控件。
在尝试修复此错误的树周后,我发现当编译器批量编译目录并在同一个dll中捆绑许多不同的自定义控件时会出现此错误。因此,当我尝试单独加载它时会抛出此异常。
所以我将有问题的自定义控件单独移动到另一个目录中,似乎我现在就避免使用它。
即使我将一些文件移动到另一个目录后再次出现。是随机的,无法与触发它的东西找到明确的联系。
因为我们发现这里的主要问题是批处理编译(batch="true"
)在同一个dll上编译许多自定义控件,一种说法编译器不这样做的方法是{{3参数。我使用它的值为100,问题再次出现,现在我将它降低到40并测试它。
maxBatchGeneratedFileSize="40"
答案 0 :(得分:11)
当您打开批处理并在目录级别具有某种形式的循环引用时,可能会发生这种情况。
请参阅此answer以确切了解我在这种情况下的“循环引用”的含义,因为含义非常微妙。
如果您设法打破周期(例如,将用户控件移到其他位置),则不会遇到此问题。
我认为从理论上讲,这只能由一个周期引起,但有时它们很难被发现。
我会给你一个替代解决方案,我觉得它会起作用并且很容易尝试(即使它有点像黑客)。在给您带来问题的用户控件中,在指令中添加以下属性:
<%@ Control Language="C#" [...] CompilerOptions="/define:dummy1" %>
如果你看到这个与其他一些控件,你可以添加相同的东西,但使用dummy2,dummy3等...
这将导致不对这一个用户控件进行批处理,因为它具有与其他用户控件不同的编译需求。从技术上讲,您可以添加任何C#命令行作为CompilerOptions
,但虚拟/define
是最简单,最无害的。
但与全局关闭批处理不同,性能影响最小,因为只有非常小的页面子集不会被批处理。
顺便说一句,毋庸置疑,你所看到的是ASP.NET中的一个错误,而且这个bug已经有10年多了!也许在某些时候应该得到解决:)答案 1 :(得分:2)
为了跟踪问题的原因,我认为了解控件的创建方式非常重要。请参阅此阅读:Turning an .ascx User Control into a Redistributable Custom Control。
第1步:创作用户控件
要创作用户控件,最好从一个空的应用程序开始 除了ascx之外什么也没有。而用户的创作 控制使用“标准”技术,有一些限制 你需要知道它才能成功转变 一个独立的自定义控件。 主要限制是用户控件需要自包含。也就是说,它不能依赖于应用程序的全局事物 像App_Code或global.asax。原因是因为 目标是将UserControl转换为独立的DLL,它会 如果它依赖于不属于其他代码的代码,则在其他应用程序中中断 DLL 即可。这个规则的一个例外是UserControl可以 依赖于bin目录中(或者在bin目录中)的程序集 GAC)。您只需要确保其他组件始终是 在其他应用中使用自定义控件时可用。
和
步骤3:使用发布命令预编译站点
(...)选择“使用固定命名和单页程序集”。 :此 将保证您的用户控件将被编译为单个 将具有基于ascx文件的名称的程序集。如果你不这样做 选中此选项,您的用户控件可以与之一起编译 其他页面和用户控件(如果你有的话)和程序集 会收到一个更难以使用的随机名称。
在我看来,您很可能将用户控件在GAC中编译和注册为单独的程序集,并且还包含在您的Web应用程序DLL中。
注意:也许这应该是一个评论,但我想包括前面提到的链接中的引号。我希望它有用。
答案 2 :(得分:1)
在已升级的ASP.NET网站上进行了大量调试后,我的最后一个错误是运行时的错误。
我刚刚检查了Build / Publish选项“使用固定命名和单页程序集”,它解决了我的问题:)
这里有一些有用的链接:https://msdn.microsoft.com/en-us/library/hh475319(v=vs.110).aspx
答案 3 :(得分:0)
当我编译asp.net MVC 4的修改版本并将新DLL导入项目时,我最近遇到了类似的问题。
不知怎的,我在web.config中引用了旧版本的DLL(包括views文件夹中的web.config)
我的案例中的错误被抛出,因为这两个DLL是不同的版本。 4.0.0和4.1.0。 也许你应该研究一下。 也许指定编译文件的版本(我猜的是DLL)
我希望这有助于您解决问题。
其他提示:我猜你有某种版本控制系统?如果是,请在开始之前将所有更改还原,并仔细查看代码以及更改的模型/控件以及方式。 如果您没有使用VCS ...您无法做很多事情来还原更改。你应该开始使用VCS。
答案 4 :(得分:0)
我注意到有时设计师会创建第二个CodeBehind设计器文件,例如你会:
OneProduct_MediumImage.ascx
OneProduct_MediumImage.ascx.cs
OneProduct_MediumImage.ascx.designer.cs
OneProduct_MediumImage.ascx.designer1.cs
如果您在解决方案资源管理器集中没有“显示所有文件”选项,则不会注意到,但对于Web项目,编译器将编译该文件夹中的所有文件,而不仅仅是项目中包含的文件。
其次,如果您的项目是“网站项目”,则没有名称空间,这可能导致许多奇怪的错误。看看这个问题:Namespace problem .net
最后,我设法通过在控制文件上设置ClassName
属性来解决看似随机的UserControl错误,例如:
<%@ Control Language="cs"
AutoEventWireup="false"
CodeBehind="OneProduct_MediumImage.ascx.cs"
Inherits="ASP.Modules_OneProduct_MedioumImage"
ClassName="OneProduct_MediumImageControl" %>