2012-02-03 31 views
0

我有一個aspx頁面,它在App Code文件夾doSomething(int[] x)的一個類中使用了一個方法。我將函數定義更改爲使用IEnumerable而不是數組:doSomething(IEnumerable<int> x)。接下來,我預編譯了網站,使用「允許網站更新」,併發布了新的App_Code.dll。現在,頁面的預編譯版本在運行時給出了服務器錯誤:「未找到方法」。
如果我還發布了爲該頁面生成的「App_Web_ [page] .aspx。[random] .dll」,它的工作原理。所以看起來函數的簽名以某種方式嵌入了編譯後的頁面......?爲什麼會這樣,並且在改變現有代碼時是否有辦法避免這個問題?
我不想更新我所有的頁面DLL,只要我更改我的公共類中的代碼。爲什麼當它使用的方法更改時,需要重新編譯的頁面?

+2

難道你懶得看MSDN上,理解類型ASP.Net編譯。http://msdn.microsoft.com/en-us/library/ie/ms178466.aspx http:/ /msdn.microsoft.com/en-us/library/ie/ms366723.aspx – Lloyd 2012-02-03 10:34:30

回答

2

當一個頁面編譯它看起來在所有的方法簽名,基本上鎖定下來。如果您更改被調用方法的簽名,那麼在重新編譯之前,頁面將無法找到它。

例如假設你有一個像

public class Dog { 
    public void Walk(Int32 distance) { 
    /// blah blah 
    } 
} 

一類,你把這個在後面的頁面代碼:

protected void MyButtonClick(....) { 
    Dog d = new Dog(); 
    d.Walk(3000); 
} 

當此編譯下來的頁面將期望有一個走法Int32簽名。

現在,讓我們說我們改變了走法在狗類:

public void Walk(Int16 distance) { 
    // blah blah 
} 

(是的,愚蠢的變化,但它突出的問題)。 此時,頁面將無法找到採用Int32參數的Walk方法,因此會崩潰。


它可能看起來不錯,只是部署一個組件,你認爲你需要,但問題的事實是可能存在的任何數量的發生的代碼更改的,所以這是一個嚴重的壞習慣。

最好就是確保整個項目是一致的。即使是大型網站也不需要很長時間才能部署。

當然,我覺得用網站項目反正自己和不良做法。部署未編譯代碼服務器(真的不好),VS搜索您的驅動器來更新項目中的引用,即使你已經明確告訴它要使用的組件(通常是意外,從來沒有好),其在所有的主代碼一個共同的App_Code文件夾(限制),等我可以繼續下去,並在這裏...

+0

這是一個偉大的答案。我試圖通過將版本控制系統的日誌處理成要上傳的文件列表來緩解代碼中未知更改的問題。這樣,我確切知道哪些文件發生了變化,以及需要發佈哪些編譯文件。或者我想...... – 2012-03-08 15:47:03

1

如果它是一個Web應用程序,那麼你需要重新編譯每次你改變服務器端代碼 - 如果它是在一個單獨的程序或在你的web應用程序的App_Code文件夾無所謂。

唯一網站(而不是web應用程序)允許您更改代碼而無需重新編譯。

+0

這是一個網站項目。 – 2012-02-03 10:35:16

+0

您是使用發佈工具發佈網站還是正在調試?如果您已發佈,則需要每次重新發布。 – 2012-02-03 10:37:41

+0

這是不完全正確的,「網站」項目是由運行時根據請求動態編譯的,因此它們確實只是不明確地編譯。 MSDN http://msdn.microsoft.com/en-us/library/ie/ms366723.aspx – Lloyd 2012-02-03 10:39:33

0

您需要重新編譯,因爲你的網頁發佈,並輸出到bin文件夾中的DLL。這個DLL正在尋找一個簽名的方法:

doSomething(int[]) 

它不存在了。每次發佈時都要更新所有內容。


我相信「更新」標誌允許您更新的aspx代碼(即標記),但代碼隱藏文件將被編譯了。

0

以下幾種變化可能導致運行時異常:
更改方法的簽名,或屬性的類型。如果 受影響的部件由已編譯的頁面引用,一個 會拋出異常。如果整個站點重新編譯,則某些簽名更改不會導致編譯或運行時錯誤 。對於 例如,代碼的Response.Write(ClassA.MethodA()在 一個.aspx頁面將編譯和運行細治法是否返回一個int或短。 但如果在.aspx頁面已經被編譯並更改返回 從int到short無需重新編譯,因爲編譯後的代碼預計INT 簽名運行時 會拋出異常型治法的。

http://msdn.microsoft.com/en-us/library/ms366723.aspx#sectionToggle5