.NET1.x升級到.NET2.x問題小結

來源:互聯網
上載者:User

這幾天升級了一下原來的1.1項目,發現了一些問題,總結一下放在這裡,也提醒還沒有來得及升級或準備升級的朋友,升級的過程中少走彎路,少浪費時間。

 

1.Global.asax檔案的處理形式不一樣,轉化後將出現錯誤,在vs2003中Global.asax具有代碼後置檔案,2.0下, 將代碼分離檔案移到 App_Code 目錄下,以便使其自動變為可通過應用程式中的任意 ASP.NET 頁面訪問。“Code-behind”屬性將從 ASAX 檔案的指令中刪除。vs2005則直接把代碼寫在Global.asax。所以需要刪除轉化過來的檔案重新加入,並把相應的代碼copy過來。

22.0沒有了專案檔。 在 1.1 應用程式中,專案檔包含產生設定、對外部程式集的引用以及項目中的檔案清單。而在 2.0 應用程式中,不再需要版本設定和檔案清單,因為 Web 項目目錄下的所有檔案都被視為 Web 項目的一部分。

3代碼分離模式
在 ASP.NET 1.1 中,代碼分離模式使內容(例如 test.aspx)與代碼(例如 test.aspx.cs)分離。內容頁面從代碼分離頁面繼承而來,代碼分離頁麵包含使用者和設計器產生的程式碼。
ASP.NET 2.0 通過使用局部類來增強代碼分離模式,使用 partial 關鍵字可以將單個類的代碼分隔到兩個獨立的檔案中。它允許一個類跨越多個檔案。在新的代碼分離模式中,內容頁面從編譯的類繼承而來,它由相應的代碼分離頁面以及自動產生的存根檔案組成,存根檔案用於為內容頁面中使用的控制項定義欄位聲明。此項更改使自動產生的程式碼與使用者的代碼分離,並且使代碼分離頁面顯著變小且更加簡潔。局部類結構還降低了由於編輯設計器產生的程式碼而不小心破壞頁面的風險。
如果出錯請檢查是否有partial 關鍵字,否則添加 partial 關鍵字。

4.語法檢查。asp.net1.1程式,編譯時間不會檢查aspx、aspcx等檔案中的語法錯誤,而vs2005編譯時間會檢查項目中所有的aspx、aspcx等檔案中的文法,所以如果有語法錯誤,會導致編譯無法通過。

5.控制項聲明。如果在 .aspx 頁面上聲明了所有控制項,則從代碼分離檔案中刪除所有控制項聲明,否則報錯:重複定義。

6.(僅限於 C#)將事件掛鈎代碼從代碼分離檔案的 InitialzeComponent 函數移到 .aspx 頁面中。請注意,此操作不適用於自動調用的事件,包括 Page_Init、Page_Load、Page_DataBind、Page_PreRender、Page_Unload、Page_Error、 Page_AbortTransaction 和 Page_CommitTransaction。

7.部署方式(先行編譯、完整編譯、可更新網站等)。在 1.x 中,Web 應用程式是作為一個大型程式集而先行編譯和部署的。內容頁面(*.aspx)不在伺服器上編譯,但可以在伺服器上編輯。藉助新的頁面編譯模式和目錄結構,您就可以使用多種不同的配置來部署 ASP.NET 2.0 應用程式。一種情況,您可以先行編譯所有的 ASPX 頁面並部署由完全編譯好的程式集組成的 Web 應用程式。在這種模式下,您不能在伺服器上輕鬆地更改該應用程式。另一種情況,您可以在不先行編譯任何代碼的情況下部署應用程式。在這種配置下,您可以直接在伺服器上更改該應用程式中的 .aspx 頁面、代碼分離檔案或其他任何代碼。當使用者請求伺服器上的頁面時,頁面將被動態編譯。

8..aspx 頁面中的所有 CodeBehind 屬性更改為 CodeFile 屬性
CodeBehind: 指定包含與頁關聯的類的已編譯檔案的名稱。該屬性不能在運行時使用。
提供此屬性是為了與以前版本的 ASP.NET 的相容,以實現程式碼後置功能。在 ASP.NET 2.0 版中,應改用 CodeFile 屬性指定該源檔案的名稱,同時使用 Inherits 屬性指定該類的完全限定名稱。
CodeFile 指定指向頁引用的程式碼後置檔案的路徑。此屬性與 Inherits 屬性一起使用可以將程式碼後置源檔案與網頁相關聯。此屬性僅對編譯的頁有效。

9.將所有獨立的代碼檔案和AssemblyInfo.cs都被移到 App_Code 目錄下。
但運行轉換嚮導之後,您可能會發現某些代碼分離檔案(例如,*.aspx.cs 或 *.ascx.vb)被移到 App_Code 目錄下。這表明代碼分離檔案的內容頁面含有格式不正確的 Codebehind 指令,並且沒有進行正確設定。也就是說,轉換嚮導不能確定該代碼分離檔案是否實際綁定到某個特定的 .aspx 頁面。

10.Web 服務
在 ASP.NET 1.x 中,Web 服務 (.asmx) 自動拆分到空白標題頁面 (.asmx) 和包含實際方法的代碼分離檔案中。
Asp.net2.0下:
• 將代碼分離類移到 App_Code 目錄下,以便使其自動變為可通過應用程式中的任意 ASP.NET 頁面訪問。 
• 更改 .asmx 檔案中的 CodeBehind 屬性,以便指向新位置。
(請注意,代碼分離檔案不使用局部類,因此繼續使用 CodeBehind 屬性。) 
• 將所有的預設、Friend 和 Internal 範圍的聲明更改為 Public。

在1.1到2.0的升級過程中,你遇到過什麼樣的問題呢?可以寫下來讓大家共同學習,少走彎路。

    當你準備將Web應用程式從ASP.NET 1.1升級到ASP.NET 2.0,你將面對這樣一個cookie問題:在ASP.NET 1.1應用程式中用戶端儲存的所有cookie將失效。

    部落格園也遇到了這樣的問題,對部落格園來說,意味著所有使用cookie的使用者都需要重新登入,雖然這不是一個很大的問題,但的確給大家帶來了麻煩,如果忘記了密碼,將更加麻煩。

    對於一個非常重視使用者滿意度的網站來說,應該努力去解決這個問題。部落格園希望儘可能減少升級帶來的影響,所以這兩天我一直在研究這個問題並找到瞭解決方法。

    問題的原因是:當程式從ASP.NET 1.1升級到於ASP.NET 2.0後,ASP.NET 2.0使用新的演算法與金鑰組用戶端發送過來的cookie進行解密,這樣導致ASP.NET中產生的cookie在ASP.NET 2.0中失效。在ASP.NET 1.1中,使用3DES演算法對cookie的內容進行加密,而在ASP.NET 2.0中預設使用Advanced Encrypted Standards (AES)演算法進行解密,這是引起問題的原因之一,通過相應的設定可以將ASP.NET 2.0中將cookie密碼編譯演算法改為3DES,只需在web.config中加上:.但這樣做之後問題依然存在,因為解密時除了需要相同的演算法,還需要相同的密鑰。如果沒有在machineKey中指定密鑰,ASP.NET 2.0會預設會使用隨機產生的密鑰,這個隨機密鑰由System.Web.HttpRuntime.SetAutogenKeys()產生並儲存於System.Web.HttpRuntime.s_autogenKeys中,通過反射你可以擷取這個值。ASP.NET 1.1的machineKey是在machine.config中進行設定的,預設也是使用隨機密鑰:.問題就出在不同的隨機密鑰上。如果你在原來的ASP.NET 1.1中指定了密鑰,那就不存在這個問題了,但一般在使用Web farm時,才會考慮這一點。所以通常情況都是使用隨機密鑰。ASP.NET會為不同的應用程式產生不同的隨機密鑰,這個用戶端cookie失效問題會出一在很多情況下,比如:重裝系統、將ASP.NET應用程式移至另外一台電腦,將Web應用程式移到不同的虛擬目錄中等等。

    如何解決這個問題呢?

    原理很簡單,只要我們知道在ASP.NET 1.1中隨機產生的密鑰的值,然後在ASP.NET 2.0應用程式的web.config中進行指定就行了,這裡的密鑰有兩個:一個是加密金鑰decryptionKey,一個是散列計算密鑰validationKey(防止cookie被中途篡改)。假如我們知道密鑰分別為:X、Y,那在web.config進行如下設定就能解決問題:而難題就在於如何得到ASP.NET 1.1中隨機產生的密鑰的值。金鑰儲存區在LSA(Windows Local Security Authority)中,但我沒找到可以從LSA擷取密鑰的方法。

    由於部落格園主要是解決登入cookie的問題,而這個cookie是在System.Web.Security.FormsAuthentication. SetAuthCookie(string userName, bool createPersistentCookie)中產生的,所以我就從ASP.NET 1.1的System.Web.Security.FormsAuthentication的原始碼下手,發現了System.Web.Configuration.MachineKey,經過進一步對MachineKey的原始碼進行研究,在MachineKey的MachineKeyConfig中發現了兩個密鑰分別存在於s_validationKey與s_oDes這兩個私人靜態成員中(發現這個費了不少功夫),validationKey的值直接儲存於s_validationKey中,而decryptionKey儲存於s_oDes.Key中。由於MachineKey是internal class,MachineKeyConfig是私人類型,那兩個成員是私人靜態成員,無法直接存取。這時,該是。NET中強大的反射功能發揮作用的時候了。通過反射得到這兩個值,需要注意的是這兩個值的類型是Byte[],通過測試發現直接轉換成字串產生的密鑰無效,需要通過反射調用System.Web.Configuration.MachineKey.ByteArrayToHexString(Byte[], Int32) 轉換成字串。

    今天晚上終於解決了這個問題,好興奮!中途幾次想放棄,但想到在部落格園程式升級到ASP.NET 2.0後,會因為這個問題給很多人帶來麻煩,雖然只需要重新登入一下就行了,但我還是覺得要解決這個問題,做程式開發不就是儘可能給使用者帶來方便嗎?

    解決了這個問題就為部落格園網站升級到ASP.NET 2.0作好了進一步的準備。

費了好一袋煙工夫把CommunityServer升級到了Asp.Net2.0平台,一點心得:

vs2005可以很方便的幫我們把vs2003開發的asp.net1.1版本項目升級到vs2005開發的asp.net2.0版本,從vs2005裡面開啟vs2003的解決方案或者專案檔,會有嚮導幫我們自己完成升級工作。一部分asp.net1.1的項目做完這個工作就足夠了。

不過更多的時候不會這麼順利,還要注意一些問題:

  • vs2003開發的asp.net1.1程式,不會檢查aspx、aspcx等檔案中的語法錯誤,而vs2005會檢查項目中所有的aspx、aspcx等檔案中的文法,所以如果有語法錯誤,會導致編譯無法通過。
  • vs2003中,如果用的是預設的代碼綁定方式,那麼在aspx檔案(以aspx檔案為例,ascx檔案也有這個問題)中申明的伺服器端控制項,會在aspx檔案對應的aspx.cs檔案中,產生一個對應的申明,例如aspx中有一個TextBox,ID是MyTextBox,那麼在aspx.cs中,會申明一個"protected TextBox MyTextBox;",而在vs2005中,這個申明是多餘的,所以升級後要去除這些多餘的申明。
  • 如果有程式採用了asp.net1.1下的Membership——使用MemberRole.dll,要升級到asp.net2.0下的Membership,需要做如下工作:
    • 刪除所有項目中對"MemberRole.dll"的引用,添加"System.Configration"的引用
    • 改變命名空間ScalableHosting.Profile -> System.Web.Profile;ScalableHosting.Security -> System.Web.Security; 同時添加using System.Configuration;
    • 移除所有MemberRole.dll相關的Membership配置,參照以前的Membership配置,增加asp.net2.0支援的Membership配置,更新Membership的預存程序。
  • CCS1.1 for asp.net2.0的下載:http://www.communityserver.cn/builds

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.