ASP.Net错误:“类型”foo“存在于”temp1.dll“和”temp2.​​dll“ (第2页) [英] ASP.Net error: “The type ‘foo’ exists in both ”temp1.dll“ and ”temp2.dll" (pt 2)

查看:250
本文介绍了ASP.Net错误:“类型”foo“存在于”temp1.dll“和”temp2.​​dll“ (第2页)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

解决方案:



我也在同一时间移动了ashx和asmx文件。 WebService / WebHandler指令的Class属性指向错误的命名空间。故事的道德是确保您查看所有 的标记为* x 文件,您可以通过右键单击来更改命名空间并选择查看标记。






我遇到的问题与这个问题此链接,但没有一个答案解决了我的问题。 (编辑:设置web.config批处理属性有效,但这是一个掩护,而不是一个解决方案)



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



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



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



那么这里是幻影参考来自我可以如何解决这个问题?



更新:我正在grepped我的工作目录中的每个文件的解决方案和我的临时目录的旧类名,并删除每个包含它的文件。然后我重新命名为原始的,坏的名称,我仍然收到错误。


'/'应用程序中的服务器错误。
编译错误说明:在编译
时,
出现在为
请求提供服务所需的资源中。请查看以下
具体的错误详细信息,并适当修改
源代码。



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



源错误:



行1098:第1099行:

[System.Diagnostics .DebuggerNonUserCodeAttribute()]
行1100:private
global :: ASP.dashboard_badusercontrol_ascx
@__ BuildControlMyBadUserControl(){
行1101:

global :: ASP .dashboard_badusercontrol_ascx
@__ctrl;第1102行:



源文件:c:\Docunts和
Settings\me\Local
Settings\Temp\Temporary ASP .NET
Files \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个寄存器指令:

 <%@注册src =BadUserControl.ascxtagname =BadUserControltagprefix =uc1%> 
<%@ Register src =OtherUserControl.ascxtagname =OtherUserControltagprefix =uc2%>

这些情况工作:


  1. 我保留BadUserControl.ascx的名字。
    我在同一个命名空间中的一个页面上有一个Register指令:

     <%@注册src =BadUserControl .ascxtagname =BadUserControltagprefix =uc1%>我将BadUserControl.ascx改为GoodUserControl.ascx
    I有2个注册指令:

     <%@注册src =GoodUserControl.ascxtagname =GoodUserControltagprefix =uc1 %> 
    <%@ Register src =OtherUserControl.ascxtagname =OtherUserControltagprefix =uc2%>


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

     <%@注册src =AnotherUserControl.ascxtagname =AnotherUserControltagprefix =uc1%> 
    <%@ Register src =OtherUserControl.ascxtagname =OtherUserControltagprefix =uc2%>



解决方案

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



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



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



至于为什么重命名文件修复它,这可能是由于它改变排序哪些文件被处理,这是有点任意的。可能的是,如果你把它重新命名为别的东西,你会看到它再次发生。



坦率地说,回头看我有这样的希望,在运行时,要更早地捕捉这些情况。我们选择当前秋季设计的原因是为了尽可能避免失败,但是这是一个代价:当有什么不对,这是一个痛苦的抓住它:)






原始答案:
简而言之,问题是当批量打开(默认情况下)时,应避免具有目录级循环依赖关系。让我解释一下我的意思。



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




  • 在folder1中:page.aspx和uc2.ascx

  • 在forder2中: uc1.ascx



并且说page.aspx引用uc1.ascx(通过@register指令),uc1.ascx引用uc2.ascx。在文件级别,这是非常好的,但在目录级别,有一个循环依赖:folder1引用了folder2中的某些东西,它引用了folder1中的某些东西。



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



实际上有一种方法来轻松检测您的站点是否具有这样的文件夹级循环依赖关系。在VS控制台窗口中,转到您网站的根目录并运行:

  aspnet_compiler -v foo -p。 

如果您有文件夹级别的循环依赖关系,您将收到以下错误:

  /foo/Sub/UC1.ascx(2):错误ASPPARSE:不允许循环文件引用。 

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



但是,如果可以避免文件夹级别的循环依赖性,那么最好的办法是。如果您开始将每个文件夹作为生成程序集的组件,这实际上是有意义的,并且可以帮助您的站点更加模块化。



是在编译系统中称之为错误也至少有一个限制也是公平的。但是一旦你意识到这一点,这是很容易避免的。


Solution:

I had also moved ashx and asmx files at the same time as this. The Class attribute of the WebService/WebHandler directives were pointed at the wrong namespace. The moral of the story is to make sure you view the markup for all as*x files you change the namespace for by right-clicking on them and choosing "View Markup".


I'm experiencing the same problem as in this question and this link, but none of the answers fixed my problem. (edit: Setting the web.config batch attribute works, but that's a coverup, not a solution)

The problem I'm having is with a User Control that I moved from the root directory to a subdirectory within the same Web Application project. It used to work fine before I moved it. When I moved it it started giving me the error message.

It's saying that the class name exists in two dll files in Temporary ASP.NET Files. Sure enough, when I open Reflector, it's in two dlls.

If I rename the class and ascx file, everything works fine. No usages of the original name exist within any of the files in my entire application. When I rename the file, I opened all of the dll files in Temporary ASP.NET Files with Reflector, and no references to the original class name exists.

So where's this phantom reference coming from how can I fix this?

Update: I literally grepped every file in my working directory for the solution and my temp directory for the old class name and deleted every file that contained it. I then renamed back to the original, broken name and I still get the error.

Server Error in '/' Application. Compilation Error Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error ssage: CS0433: The type 'ASP.dashboard_badusercontrol_ascx' exists in both 'c:\Docunts and Settings\me\Local Settings\Temp\Temporary ASP.NET Files\root\3c2b7e1f\2e8a7620\App_Web_badusercontrol.ascx.a57ad085.iljdmp1p.dll' and 'c:\Docunts and Settings\me\Local Settings\Temp\Temporary ASP.NET Files\root\3c2b7e1f\2e8a7620\App_Web_bhdqaimy.dll'

Source Error:

Line 1098: Line 1099:
[System.Diagnostics.DebuggerNonUserCodeAttribute()] Line 1100: private global::ASP.dashboard_badusercontrol_ascx @__BuildControlMyBadUserControl() { Line 1101:
global::ASP.dashboard_badusercontrol_ascx @__ctrl; Line 1102:

Source File: c:\Docunts and Settings\me\Local Settings\Temp\Temporary ASP.NET Files\root\3c2b7e1f\2e8a7620\App_Web_foo.aspx.a57ad085.1nw6dais.0.cs Line: 1100


Edit: Ok, so I did some more testing on what works and doesn't work. Let's say the original file name was "BadUserControl.ascx" in namespace "MyNamespace".

I moved the file to a directory called "NewDirectory" and changed the namespace to "MyNamespace.NewDirectory". There are no copies of "BadUserControl.ascx" anywhere else on my HDD. I double-checked my TFS history to ensure the ONLY difference is the addition of ".NewDirectory" to the namespace in the markup and code-behind files.

Inside of this namespace are two other user controls named "OtherUserControl" and "AnotherUserControl".

This situation fails: I have 2 Register directives:

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

These situations work:

  1. I keep "BadUserControl.ascx" named as is. I have 1 Register directive on a page in the same namespace:

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

  2. I change "BadUserControl.ascx" to "GoodUserControl.ascx" I have 2 Register directives:

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

  3. 2 Register directives without BadUserControl.ascx at all:

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

解决方案

UPDATE: ok, as you found, the circular reference was the wrong guess, as there are other situation that may cause similar behavior.

The more general way to describe the problem is that batching at runtime works in a very permissive way which can mask problems. Basically, we try to batch everything in one folder, but if we get a compile error when compiling that batch, we fall back to individual file compilation. In many cases that works fine, but sometimes, this can lead to a given page getting compiled twice (similar to what I described below, but for a different reason).

On the other hand, aspnet_compiler works in a strict way, where if batching fails it fails altogether and does not fall back. That's why running this tool is a great way to locate various type of issues (or latent issues) that can be far from obvious at runtime. I guess we didn't do a good job evangelizing this tool for this purpose :)

As for why renaming the file fixed it, this may be caused by it changing the ordering in which files are processed, which is a bit arbitrary. It may be that if you rename it to something else, you'll see it happen again.

Frankly, looking back I kind of wish we had made this batching behavior strict at runtime, to catch those situations earlier. The reason we chose the current fall back design was to avoid failing whenever possible, but this came with a price: when something is wrong, it's a pain to catch it :)


ORIGINAL ANSWER: In short, the problem is that when batching is turned on (and it is by default), you should avoid having directory level circular dependencies. Let me explain what I mean by that.

Here is an example. Say you have:

  • In folder1: page.aspx and uc2.ascx
  • In forder2: uc1.ascx

And say that page.aspx references uc1.ascx (via a @register directive), and that uc1.ascx references uc2.ascx. At the file level, that’s perfectly fine, but at the directory level, there is a circular dependency: folder1 references something in folder2, which references something in folder1.

Why this is problematic has to do with how batching works: when you request the page, it first tries to compile everything in folder1 together. But since folder1/page.aspx references folder2/uc1.ascx, it needs to compile folder2 before it can do folder1. But then uc1 uses uc2, meaning it must first do folder1! At this point, ASP.NET detects the situation and tries to make the best of it by compiling uc2.asc by itself. While this allows some scenarios to work, it can also cause weird things because some items end up compiled in two assemblies. Here, uc2.ascx would be both compiled by itself and with the folder1 batch.

There is actually a way to easily detect if your site has such folder level circular dependencies. From a VS console window, go to the root of your site and run:

aspnet_compiler -v foo -p .

If you have folder level circular dependencies, you’ll get some errors that look like:

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

The cheap way to avoid this issue is what you already know: disable batching. Now at least you know why that works :)

But the better thing to do if you can is to avoid the folder level circular dependencies. If you start thinking of each folders as a ‘component’ which produces an assembly, that actually makes sense, and can help make the pieces of your site more modular.

Yes, it’s also fair to call this a ‘bug’ in the compilation system, or at least a limitation. But once you’re aware of it, it’s fairly easy to avoid.

这篇关于ASP.Net错误:“类型”foo“存在于”temp1.dll“和”temp2.​​dll“ (第2页)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆