Asp.net

ASP.Net 錯誤:““temp1.dll”和“temp2. dll”中都存在“foo”類型(第 2 部分)

  • October 3, 2019

解決方案:

我還同時移動了 ashx 和 asmx 文件。WebService/WebHandler 指令的 Class 屬性指向了錯誤的命名空間。這個故事的寓意是確保您通過右鍵點擊它們並選擇“查看標記”來查看更改名稱空間的所有文件的標記。 as*x


我遇到了與這個問題這個連結相同的問題,但沒有一個答案能解決我的問題。(編輯:設置 web.config 批處理屬性有效,但這是一種掩飾,而不是解決方案)

我遇到的問題是我從根目錄移動到同一個 Web 應用程序項目中的子目錄的使用者控制項。在我移動它之前它曾經工作得很好。當我移動它時,它開始給我錯誤消息。

就是說類名存在於 Temporary ASP.NET Files 的兩個 dll 文件中。果然,當我打開Reflector時,它在兩個dll中。

如果我重命名類和 ascx 文件,一切正常。在我的整個應用程序的任何文件中都沒有使用原始名稱。當我重命名文件時,我使用 Reflector 打開了 Temporary ASP.NET Files 中的所有 dll 文件,並且不存在對原始類名的引用。

那麼這個幻影參考來自哪裡,我該如何解決呢?

更新:我從字面上 grep 了解決方案的工作目錄中的每個文件,以及舊類名的臨時目錄,並刪除了包含它的每個文件。然後我重命名回原來的,損壞的名稱,我仍然得到錯誤。

“/”應用程序中的伺服器錯誤。編譯錯誤描述:在編譯服務此請求所需的資源期間發生錯誤。請查看以下特定錯誤詳細資訊並適當修改您的原始碼。

編譯器錯誤消息:CS0433:“c:\Docunts and Settings\me\Local Settings\Temp\Temporary ASP.NET Files\root\3c2b7e1f\2e8a7620\App_Web_badusercontrol.ascx.a57ad085.iljdmp1p”類型中存在“ASP.dashboard_badusercontrol_ascx”類型.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 行:私有 global::ASP.dashboard_badusercontrol_ascx @__BuildControlMyBadUserControl() { 第 1101 行:

global::ASP.dashboard_badusercontrol_ascx @__ctrl; 第 1102 行: 源文件:c:\Docunts and 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 個註冊指令:

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

這些情況有效:

  1. 我保持原樣命名“BadUserControl.ascx”。我在同一命名空間中的頁面上有 1 個註冊指令:
<%@ Register src="BadUserControl.ascx" tagname="BadUserControl" tagprefix="uc1" %>
  1. 我將“BadUserControl.ascx”更改為“GoodUserControl.ascx”我有 2 個註冊指令:
<%@ Register src="GoodUserControl.ascx" tagname="GoodUserControl" tagprefix="uc1" %>
<%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>
  1. 2 完全沒有 BadUserControl.ascx 的註冊指令:
<%@ Register src="AnotherUserControl.ascx" tagname="AnotherUserControl" tagprefix="uc1" %>
<%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>

更新:好的,正如您所發現的,循環引用是錯誤的猜測,因為還有其他可能導致類似行為的情況。

描述問題的更一般的方法是執行時批處理以一種非常寬鬆的方式工作,可以掩蓋問題。基本上,我們嘗試將所有內容批處理到一個文件夾中,但如果在編譯該批處理時出現編譯錯誤,我們將退回到單個文件編譯。在許多情況下工作正常,但有時,這可能導致給定頁面被編譯兩次(類似於我在下面描述的,但出於不同的原因)。

另一方面,aspnet_compiler 以嚴格的方式工作,如果批處理失敗,它會完全失敗並且不會回退。這就是為什麼執行此工具是定位在執行時可能不明顯的各種類型問題(或潛在問題)的好方法。我想我們沒有很好地為此目的宣傳這個工具:)

至於為什麼重命名文件會修復它,這可能是由於它改變了處理文件的順序造成的,這有點武斷。如果您將其重命名為其他名稱,您可能會看到它再次發生。

坦率地說,回想起來,我有點希望我們在執行時嚴格執行這種批處理行為,以便更早地捕捉到這些情況。我們選擇目前備份設計的原因是盡可能避免失敗,但這也是有代價的:當出現問題時,很難抓住它:)


原始答案:簡而言之,問題在於打開批處理時(預設情況下),您應該避免目錄級別的循環依賴。讓我解釋一下我的意思。

這是一個例子。假設你有:

  • 在文件夾 1 中: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,意思是它必須先做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.

避免此問題的廉價方法是您已經知道的:禁用批處理。現在至少你知道為什麼會這樣了:)

但如果可以的話,最好的辦法是避免文件夾級別的循環依賴。如果您開始將每個文件夾視為生成程序集的“組件”,那實際上是有道理的,並且可以幫助使您的站點的各個部分更加模組化。

是的,將其稱為編譯系統中的“錯誤”也是公平的,或者至少是一個限制。但是一旦意識到這一點,就很容易避免。

引用自:https://stackoverflow.com/questions/2596118