不能投[B];相同的上下文(默认);不同的临时文件

时间:2011-07-23 02:38:16

标签: asp.net iis .net-4.0

我很难找到为什么会发生以下错误。我将在错误描述下面概述令人费解的方面。

[A] ASP.common_resultmessagepanel_ascx 无法投放到[B] ASP.common_resultmessagepanel_ascx

A类来自'App_Web_resultmessagepanel.ascx.38131f0b.2c4hpv_z,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null'
在位置的“默认”上下文中 'C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Temporary ASP.NET Files \ MyWebApp \ dc3e0df6 \ ba1606c8 \ App_Web_resultmessagepanel.ascx.38131f0b.2c4hpv_z.dll'。

B类来自'App_Web_wz3shqfq,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null'
在位置的“默认”上下文中 'C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Temporary ASP.NET Files \ MyWebApp \ dc3e0df6 \ ba1606c8 \ App_Web_wz3shqfq.dll'。

错误中引用的类是从System.Web.UI.UserControl继承并实现System.Web.UI.ITextControl的Web用户控件。
控件已在主页面上注册和使用。父主页面或实现页面都没有控件实例。
类和标记页面都在Web应用程序项目中。
例外情况不会作为应用程序代码的直接结果发生它发生在内部.NET Framework代码执行期间。
该项目是一个Web应用程序,而不是一个Web站点。
Web应用程序被编译成单个二进制文件,文化特定资源被编译为一个二进制文件培养。

异常中每种类型报告的上下文是相同的,但我能够验证当发生异常时,应用程序的Temporary ASP.NET Files文件夹中实际上有2个单独的类定义。

用户控件一直存在并在应用程序中使用,但在将用户控件添加到母版页后,异常首先开始发生。

异常不会持续发生。创建临时文件后,每次请求页面时都会发生异常。如果有任何原因导致临时文件被清除或重新创建,那么是否将再次创建重复的临时类定义/ DLL是随机的。这可能是web.config更改,回收应用程序池,有时甚至只是更新/重建的Web应用程序二进制文件。

堆栈跟踪的最后一位:

   ASP.Default.__BuildControl__control35(Control ctrl) in C:\Projects\ABC.Web\App_Themes\Default\CheckBox.skin:3
   System.Web.UI.ControlSkin.ApplySkin(Control control) +12
   System.Web.UI.PageTheme.ApplyControlSkin(Control control) +119
   System.Web.UI.Control.ApplyStyleSheetSkin(Page page) +61
   ASP.masterpages_mymaster_master.__BuildControlpnlResults() in C:\Projects\ABC.Web\MasterPages\MyMaster.master:10
   ASP.masterpages_mymaster_master.__BuildControl__control2(Control __ctrl) in C:\Projects\ABC.Web\MasterPages\MyMaster.master:9
   System.Web.UI.CompiledTemplateBuilder.InstantiateIn(Control container) +12
   System.Web.UI.MasterPage.InstantiateInContentPlaceHolder(Control contentPlaceHolder, ITemplate template) +87

假定的违规来源(皮肤文件C:\ Projects \ ABC.Web \ App_Themes \ Default \ CheckBox.skin中唯一的一行):

<asp:CheckBox runat="server" SkinID="FormInput" CssClass="FormLabel FormInputCheckBox" />

此时我不知道此问题是由解决方案,其配置,IIS和应用程序池引起的,还是与实际临时文件目录本身相关的内容,可能旧文件未被清除。我已经验证了操作系统没有为temp文件夹编制索引。

我担心在生产环境中,应用程序池将回收或某些配置设置将更改并导致使用重复的类定义重新创建这些临时文件,从而导致错误。每当应用程序池回收并删除临时文件时,如果错误发生直到应用程序正确加载,我们就无法测试应用程序。所以我需要找出造成重复的原因,但此时我还不知道还有哪些地方需要调查。

有什么想法吗?


我已从母版页中删除了用户控件,并将其直接放入需要它的每个页面中并实现母版页。

到目前为止,例外并未再次发生。我将再给它几天的测试时间,看它是否再次出现。

我仍然想知道为什么会发生异常。任何人都深入了解IIS如何运行.net网络应用程序,或者如何创建临时文件?


新理论!

虽然它是一个带有编译二进制文件的Web项目,但我正在运行开发的IIS实例指向项目文件夹。因此源代码文件实际上在Web路径中。我认为IIS可能会将源代码文件编译成单独的二进制文件,尤其是在应用程序池回收时。因此,计算正在创建的重复临时文件和错误。

其他开发人员在Visual Studio中运行项目时遇到错误。我不知道这会如何解释这些情况,但我也不会将其排除在原因之外。

4 个答案:

答案 0 :(得分:2)

我不确定你的情况发生了什么,但在下列情况下我发生了这件事:

网站项目类型,而非Web应用程序。

包含许多ascx usercontrols的

/Controls文件夹。

/Client/Controls包含其他ascx用户控件的文件夹,其中一些用于注册和引用/Controls用户控件。

/Controls/BadControl.ascx使用/Client/Controls/DupedControl.ascx作为子控件。

编译器在尝试将每个文件夹编译成单独的程序集时会遇到循环依赖。

/Controls/BadControl.ascx需要首先编译/Client/Controls

/Client/Controls需要首先编译/Controls

因此,编译器首先将DupedControl.ascx放入其自己的单独程序集中。然后是/Controls,然后是/Client/Controls ,其中仍然包含DupedControl

此时,DupedControl在两个独立的程序集中有两种不同的类型。 DupedControl.ascx(标记)指向正确的类型 - 让我们在文件夹的程序集中将其称为TypeA - 而BadControl的引用指向小额外程序集中的Dupe TypeB。

当使用BadControl的页面执行时,DupedControl TypeA会通过标记实例化,但BadControl会尝试将其塞入TypeB变量,导致您描述的错误。

解决方案是移动ascx文件以摆脱循环引用。我不记得肯定,但我想也许“单页组装”和“固定命名”选项也可以解决它。

所有这一切,Web应用程序项目编译为单个程序集,所以我不认为这种循环文件夹引用是可能的。也许问题出在其他地方。

答案 1 :(得分:2)

在我们团队的开发人员间歇性地看到这个错误一年半之后,我终于能够收集到足够的数据来得出一些结论。

导致错误的方案中的关键元素是Web路径中的源代码文件,以及运行应用程序的开发机器上的低可用内​​存。低内存条件导致应用程序池比专用Web托管环境更频繁地回收或释放内存。当释放包含已编译的Web应用程序代码的内存,然后请求页面时,已编译的代码将重新加载到应用程序池内存中。由于源代码文件位于Web路径中,因此.NET将从源代码文件重新编译并重新加载到内存中。

这种情况不会发生在只部署已编译的DLL和静态文件的专用托管环境中,并且在我们的生产环境中从未发生过。此外,在专用环境中使用内存时,理想情况下永远不会达到需要频繁进行应用程序池回收的程度。

Visual Studio解决方案由多个项目组成,开发人员通常具有多个VS实例,SQL Server管理实例以及其他运行的各种进程,这些进程会导致开发计算机上的可用内存不足。可用内存越低,错误发生的频率越高,越可靠。

要清除错误状态,应用程序池flush / iisreset将清除内存,然后重建通常可以解决问题。如果可用内存仍然很低,则问题可能会持续存在,直到有更多可用内存来运行应用程序。只需关闭一些应用程序或以其他方式将内存释放回操作系统就可以了。

我仍然不确定为什么通过Visual Studio的Web服务器而不是IIS运行应用程序有同样的问题,但如果它以与IIS相同的方式处理内存,那么行为是相同的。

答案 2 :(得分:0)

解决!

我有类似的问题,由LoadControl()奇怪的行为引起..而解决了在之前没有实例化我的控件。

奇怪但真实......


MyUserControl myuc = new MyUserControl(); 
myuo = (MyUserControl)Page.LoadControl("~/UserControls/MyUserCOntrol.ascx");

无效


MyUserControl myuc = (MyUserControl)Page.LoadControl("~/UserControls/MyUserCOntrol.ascx");

<强>工作原理

答案 3 :(得分:0)

我相信我们找到了解决此问题的方法。我们一直试图通过删除整个“ Temporary ASP.NET Files”文件夹来解决此问题。

在某些时候,此解决方案将不再足够好,并且错误每30分钟左右弹出一次。我们发现,仅删除负责的文件,然后重新启动有问题的应用程序的应用程序池是一个永久的解决方案(至少对我们而言)。因此,对于您而言,您将删除以下文件(粗体),然后重新启动应用程序应用程序池:

[A] ASP.common_resultmessagepanel_ascx无法转换为 [B] ASP.common_resultmessagepanel_ascx。

类型A源自“ App_Web_resultmessagepanel.ascx.38131f0b.2c4hpv_z,版本= 0.0.0.0,区域性=中性,PublicKeyToken =空” 在位置“默认”的上下文中 'C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ ASP.NET临时文件\ MyWebApp \ dc3e0df6 \ ba1606c8 \ App_Web_resultmessagepanel.ascx.38131f0b.2c4hpv_z.dll”。

类型B源自“ App_Web_wz3shqfq,版本= 0.0.0.0,区域性=中性,PublicKeyToken =空” 在位置“默认”的上下文中 'C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \临时ASP.NET文件\ MyWebApp \ dc3e0df6 \ ba1606c8 \ App_Web_wz3shqfq.dll'

这完全可以解决我们的问题。