ASP.Net 错误:“‘foo’类型存在于‘temp1.dll’和‘temp2.​​dll’中”(pt 2)

Posted

技术标签:

【中文标题】ASP.Net 错误:“‘foo’类型存在于‘temp1.dll’和‘temp2.​​dll’中”(pt 2)【英文标题】:ASP.Net error: “The type ‘foo’ exists in both ”temp1.dll“ and ”temp2.dll" (pt 2) 【发布时间】:2011-02-05 11:16:50 【问题描述】:

解决方案:

我还同时移动了 ashx 和 asmx 文件。 WebService/WebHandler 指令的 Class 属性指向了错误的命名空间。这个故事的寓意是确保您查看 all as*x 文件的标记,方法是右键单击它们并选择“查看标记”来更改命名空间。


我遇到了与this question 和this link 相同的问题,但没有一个答案能解决我的问题。 (编辑:设置 web.config 批处理属性有效,但这是一种掩饰,而不是解决方案)

我遇到的问题是我从根目录移动到同一 Web 应用程序项目中的子目录的用户控件。在我移动它之前它曾经工作得很好。当我移动它时,它开始给我错误消息。

这是说类名存在于Temporary ASP.NET Files 中的两个dll 文件中。果然,当我打开Reflector时,它在两个dll中。

如果我重命名类和 ascx 文件,一切正常。在我的整个应用程序的任何文件中都没有使用原始名称。当我重命名文件时,我使用 Reflector 打开了 Temporary ASP.NET Files 中的所有 dll 文件,并且不存在对原始类名的引用。

那么这个幻像引用来自哪里,我该如何解决这个问题?

更新:我从字面上 grep 了解决方案的工作目录中的每个文件和旧类名的临时目录,并删除了包含它的每个文件。然后我重命名回原来的损坏名称,但我仍然收到错误。

“/”应用程序中的服务器错误。 编译错误描述:一个 编译过程中发生错误 提供服务所需的资源 要求。请查看以下内容 具体错误详情并修改您的 源代码适当。

编译器错误消息:CS0433:类型 'ASP.dashboard_badusercontrol_ascx' 存在于 'c:\Docunts 和 设置\我\本地 设置\临时\临时 ASP.NET 文件\root\3c2b7e1f\2e8a7620\App_Web_badusercontrol.ascx.a57ad085.iljdmp1p.dll' 和 'c:\Docunts and Settings\me\Local 设置\临时\临时 ASP.NET 文件\root\3c2b7e1f\2e8a7620\App_Web_bhdqaimy.dll'

来源错误:

第 1098 行:第 1099 行: [System.Diagnostics.DebuggerNonUserCodeAttribute()] 第 1100 行:私人 全局::ASP.dashboard_badusercontrol_ascx @__BuildControlMyBadUserControl() 1101 行: 全局::ASP.dashboard_badusercontrol_ascx @__ctrl;第 1102 行:

源文件:c:\Docunts 和 设置\我\本地 设置\临时\临时 ASP.NET 文件\root\3c2b7e1f\2e8a7620\App_Web_foo.aspx.a57ad085.1nw6dais.0.cs 线路:1100


编辑: 好的,所以我对有效和无效的方法进行了更多测试。 假设原始文件名是命名空间“MyNamespace”中的“BadUserControl.ascx”。

我将文件移动到名为“NewDirectory”的目录并将命名空间更改为“MyNamespace.NewDirectory”。我的硬盘上的其他任何地方都没有“BadUserControl.ascx”的副本。我仔细检查了我的 TFS 历史记录,以确保唯一的区别是在标记和代码隐藏文件中的命名空间中添加了“.NewDirectory”。

在这个命名空间内部是另外两个名为“OtherUserControl”和“AnotherUserControl”的用户控件。

这种情况失败: 我有 2 个注册指令:

<%@ Register src="BadUserControl.ascx" tagname="BadUserControl" tagprefix="uc1" %> 
<%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>

这些情况有效:

    我保持原样命名“BadUserControl.ascx”。 我在同一命名空间中的页面上有 1 个注册指令:

    <%@ Register src="BadUserControl.ascx" tagname="BadUserControl" tagprefix="uc1" %>
    

    我将“BadUserControl.ascx”更改为“GoodUserControl.ascx” 我有 2 个注册指令:

    <%@ Register src="GoodUserControl.ascx" tagname="GoodUserControl" tagprefix="uc1" %>
    <%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>
    

    2 完全没有 BadUserControl.ascx 的注册指令:

    <%@ Register src="AnotherUserControl.ascx" tagname="AnotherUserControl" tagprefix="uc1" %>
    <%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>
    

【问题讨论】:

欢迎任何和所有调试建议,以赚取赏金。 能否请您提供您收到的确切编译错误消息?从您的描述中很难判断所涉及的 DLL 是生成的程序集还是 GAC/bin 程序集。 这里有错误信息。 【参考方案1】:

更新:好的,正如你所发现的,循环引用是错误的猜测,因为还有其他可能导致类似行为的情况。

描述问题的更一般的方式是运行时批处理以一种非常宽松的方式工作,可以掩盖问题。基本上,我们尝试将所有内容批处理到一个文件夹中,但如果在编译该批处理时出现编译错误,我们将退回到单个文件编译。在许多情况下可以正常工作,但有时,这可能会导致给定页面被编译两次(类似于我在下面描述的内容,但出于不同的原因)。

另一方面,aspnet_compiler 以 strict 方式工作,如果批处理失败,它会完全失败并且不会回退。这就是为什么运行此工具是定位在运行时可能不明显的各种类型问题(或潜在问题)的好方法。我想我们没有很好地为此目的宣传这个工具:)

至于为什么重命名文件会修复它,这可能是由于它改变了处理文件的顺序造成的,这有点武断。如果您将其重命名为其他名称,您可能会看到它再次发生。

坦率地说,回想起来,我有点希望我们在运行时严格执行这种批处理行为,以便更早地捕捉到这些情况。我们选择当前的后备设计的原因是尽可能避免失败,但这也是有代价的:当出现问题时,很难抓住它:)


原始答案: 简而言之,问题在于当批处理打开时(默认情况下),您应该避免目录级别的循环依赖。让我解释一下我的意思。

这是一个例子。假设你有:

在文件夹 1:page.aspx 和 uc2.ascx 在 forder2 中:uc1.ascx

然后说 page.aspx 引用 uc1.ascx(通过 @register 指令),而 uc1.ascx 引用 uc2.ascx。在文件级别,这完全没问题,但在目录级别,存在循环依赖:folder1 引用了 folder2 中的某些内容,而后者又引用了 folder1 中的某些内容。

为什么会出现问题与批处理的工作方式有关:当您请求页面时,它首先尝试将文件夹 1 中的所有内容编译在一起。但是由于folder1/page.aspx引用了folder2/uc1.ascx,所以需要先编译folder2才能做folder1。但是后来uc1用了uc2,意思是它必须先做folder1!此时,ASP.NET 检测到这种情况并尝试通过自己编译 uc2.asc 来充分利用它。虽然这允许某些场景工作,但它也可能导致奇怪的事情,因为某些项目最终编译在两个程序集中。在这里,uc2.ascx 会自己编译,也可以和 folder1 一起编译。

实际上有一种方法可以轻松检测您的站点是否具有此类文件夹级别的循环依赖项。从 VS 控制台窗口,转到站点的根目录并运行:

aspnet_compiler -v foo -p .

如果你有文件夹级别的循环依赖,你会得到一些看起来像这样的错误:

/foo/Sub/UC1.ascx(2): error ASPPARSE: Circular file references are not allowed.

避免此问题的廉价方法是您已经知道的:禁用批处理。现在至少你知道为什么会这样了:)

但如果可以的话,最好的办法是避免文件夹级别的循环依赖。如果您开始将每个文件夹视为生成程序集的“组件”,这实际上是有道理的,并且可以帮助您的网站的各个部分更加模块化。

是的,将其称为编译系统中的“错误”也是公平的,或者至少是一种限制。但是一旦意识到这一点,就很容易避免。

【讨论】:

这是一个很好的信息丰富的答案。虽然我没有循环文件引用,但在两个 完全不相关 文件上出现“错误 ASPPARSE:无法创建类型”错误:一个 asmx 和一个 ashx。由于双击这些文件默认会打开代码隐藏,所以我在移动时从未想过要查看这些文件上的标记。查看标记后,很明显“类”属性指向了错误的命名空间。修复这两个文件使我的用户控件能够正确编译。 David,我仍然很困惑为什么简单地重命名用户控件会导致此错误消失,即使其他文件中存在命名空间问题。我删除了 Temporary ASP.NET Files 和 bin/obj 目录。该站点的旧编译状态是否已存储在其他地方? 我添加了一个更新。但是要回答您的问题,编译状态不会存储在其他任何地方。更有可能的是,这是我上面描述的文件处理中任意顺序的影响。 超级答案!非常非常感谢你。这是过去几天我存在的祸根。【参考方案2】:

清理Temporary ASP.NET Files。可能是在移动之前的控件有一个组件,而在之后 - 另一个

【讨论】:

感谢您的想法。我删除了该目录中的所有内容,但问题仍然存在。 :( 您是否从“构建”菜单中进行了清理? @SLC:试试菜单是个好主意。但首先我的意思是删除%Temp%\Temporary ASP.NET Files 或类似%WINDIR%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files【参考方案3】:

这种错误是由名称空间引起的。检查所有文件的名称空间,确保没有重复文件或名称空间使用错误错误。

【讨论】:

这确实是在更改命名空间后直接发生的。我也想过这个问题,但是如果我所做的只是更改文件名和类名并保持命名空间不变,那么错误就会消失。不过我会仔细检查。 最简单的方法是删除新添加的命名空间并在项目中搜索命名空间并确保没有重复的命名空间。并检查您的 aspx 或 ascx 文件上的声明,确保它们引用了正确的命名空间。 当我删除新的命名空间时它确实有效。我发现了一些额外的信息,所以我正在编辑问题。 @Greg:如果你在后面的代码中放置了任何指向命名空间的路径,你可能需要在注册指令中使用完全相同的命名空间(MyNamespace.newdirectory) 这在技术上是一个正确的答案。这个问题隐藏在我也移动过的不相关的 asmx 和 ashx 文件的标记中。由于双击这些类型的文件会默认打开代码隐藏,我从没想过要检查它们。【参考方案4】:

我有时会通过我的网络用户控件得到这个。当我编辑不同的文件时,他们会抱怨他们存在两次。我不知道是什么疯狂导致它,但我知道如果我按空格 > 保存抱怨的控件,它会强制服务器重新编译,之后它工作正常。

【讨论】:

感谢您的好主意!我删除了用户控件中的所有内容。背后的所有标记和代码。唯一剩下的是 usings、命名空间、类名和 Control 指令。它仍然失败。 :( 我并不是建议清除用户控件的内容,只是对控件进行任何更改(例如按空格,然后再次删除)然后保存。这在编译器眼中将控件标记为“脏”,并强制它在您下次访问该页面时重新编译该控件。 很抱歉让您感到困惑。我试着只是修改它,但没有用,所以我擦掉了所有东西,它也没有用。【参考方案5】:

您的解决方案中是否有多个项目?

尝试清理 /bin 文件夹(手动)。旧的构建文件可能仍然存在于某个地方,从而阻止您构建...

另外,看看你的引用 - 也许你在重复你引用的东西的定义?

这是一个疯狂的尝试 - 但也许你已经在 GAC 中安装了那个 .dll?

【讨论】:

是的,我的解决方案中不仅有项目。我找到了整个解决方案,但找不到重复的参考。用户控件和使用它的页面都在同一个目录中。它不在 GAC 中。【参考方案6】:

我认为其中一些答案可能不合时宜。当您的代码隐藏引用的程序集版本与您的 web.config 不同时,我已经看到了这一点。例如:

(在 aspx 中引用了 1.1.0.0 版本,在 web.config 中引用了 1.2.0.0)

我的文件.aspx

<%@ Register TagPrefix="cc1" Namespace="StrongNamed.Namespace" Assembly="StrongNamed, Version=1.1.0.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" %>

web.config:

<assemblies>
    <add assembly="StrongNamed, Version=1.2.0.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"/>
...

我见过这样的情况,如果程序集的两个版本都在 GAC 中,ASP.NET 会给出你描述的错误。

【讨论】:

感谢新方向。我检查了一下,我没有在代码中的任何地方使用 Register 指令上的 Assembly 属性。我也没有通过 web.config 注册有问题的控件。【参考方案7】: 关闭所有正在运行的 Visual Studio 实例。 停止 IIS(如果正在运行,否则停止那个“devserver”) 清除 ASP.NET Temp 文件夹(完全) 清除 BIN 文件夹 启动 IIS(如果正在运行) 开始VS 重建解决方案

【讨论】:

感谢您的建议。我按照这些步骤操作,问题仍然存在。 您是否使用过清洁解决方案选项? (在 IIS 重置之间的某个地方)? 清洁解决方案仍然无法修复它。【参考方案8】:

有很多项目和文件夹,有时可能会弄乱命名空间,尤其是当您试图通过使用命名空间声明来强制执行时。

要查看这是否真的是一个问题,我会检查我的所有代码文件 - .cs 和 .designer.cs - 并删除所有命名空间声明,然后重新构建所有文件以查看是否可以解决问题。

您没有提及您使用的是什么版本的 Visual Studio 和 .net,这可能也有帮助 - 我记得在 VS2005 中处理过类似的问题。

【讨论】:

Visual Studio 2008 SP1 面向 .NET 3.5 和 WebDev 服务器。 这在技术上是一个正确的答案。这个问题隐藏在我也移动过的不相关的 asmx 和 ashx 文件的标记中。由于双击这些类型的文件会默认打开代码隐藏,我从没想过要检查它们。 生成的 Designer.cs 文件有时会不同步,我从来没有找到强制它们正确重新生成的好方法。【参考方案9】:

我至少遇到过两次这个问题。 David Ebbo 的回答绝对可以解释正在发生的事情。

在我的项目中,我创建了一个动态插入占位符的用户控件。 所以控件背后的代码是这样的:

public partial class CustomerAppointmentList : System.Web.UI.UserControl


请注意,此控件不在任何命名空间中。

在“customer.aspx.cs”后面的代码中,我动态加载了这个用户控件:


    var contentControl = (CustomerAppointmentList)LoadControl("../controls/customerappointmentlist.ascx");

因为 'CustomerAppointmentList' 类在 aspx 页面中不存在,我必须在我的 custmer.aspx 中引用它:

<%@ Reference Control="../controls/customerappointmentlist.ascx" %>

当 asp.net 编译器必须编译 customer.aspx 时,它会遇到“CustomerAppointmentList”类并将类型添加到该文件夹​​的库中。 几秒钟后,asp.net 编译器会将“CustomerAppointmentList”类添加到文件夹“controls”的另一个库中。

在外部库(projectname.web.dll)中添加接口“ICustomerAppointmentList”并修改代码后,问题就消失了。 所以:

    删除您的 aspx 文件中的“参考”部分。 为您的用户控件创建一个界面。 确保“Cu​​stomerAppointmentList”类继承自用户控件。 使用 LoadControl 时,转换为刚刚创建的界面。

我的新代码(ascx.cs):

    public partial class CustomerAppointmentList : System.Web.UI.UserControl, ICustomerAppointmentList


(aspx.cs)


var contentControl = (ICustomerAppointmentList)LoadControl("../controls/customerappointmentlist.ascx");  

【讨论】:

【参考方案10】:

尝试删除“Temporary ASP.Net Files”文件夹中的所有文件和文件夹,它在这个路径中:

c:\windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET 文件

这对我有用

【讨论】:

【参考方案11】:

对我来说,这发生在我将 PrecompiledWeb/Publish 位置设置为当前目录时,该目录也是该站点的根文件夹所在的位置。

我的网站在编译/构建时将发布文件夹视为项目的一部分,然后以这种方式查找重复项。

即不要将您网站的已发布版本放在您网站的代码文件夹中。

【讨论】:

【参考方案12】:
    首先你应该使用 vs 2013 来解决这个问题。 其次是这个错误,因为扩展名为.dll的文件并显示在浏览器上

编译器错误消息:CS0433:类型 'ASP.dashboard_badusercontrol_ascx' 存在于 'c:\Docunts 和 Settings\me\Local Settings\Temp\Temporary ASP.NET 文件\root\3c2b7e1f\2e8a7620\App_Web_badusercontrol.ascx.a57ad085.iljdmp1p.dll' 和 'c:\Docunts and Settings\me\Local Settings\Temp\Temporary ASP.NET 文件\root\3c2b7e1f\2e8a7620\App_Web_bhdqaimy.dll'

因此,您应该删除显示此错误的文件。(App_Web_bhdqaimy.dll)

【讨论】:

以上是关于ASP.Net 错误:“‘foo’类型存在于‘temp1.dll’和‘temp2.​​dll’中”(pt 2)的主要内容,如果未能解决你的问题,请参考以下文章

asp.net 配置错误

ASP.NET记录错误日志

Asp.net 身份验证错误

asp.net mvc全局错误处理

ASP.NET 错误处理

ASP.NET 性能分析 404/500 错误