使用ASP.NET MVC 3 RTM原始碼進行錯誤追蹤

本篇英文原文在:「Tracing ASP.NET MVC 3 RTM Source Code」小弟轉譯為正體中文版,並新增ASPX檢視引擎步驟。我的步驟以Visual Basic專案為主,檢視引擎用選擇使用Razor或ASPX,所需要引的原始碼專案及修改不同,所以分為兩部分,相同的步驟,我使用Visual Basic專案,可正常執行及追蹤錯誤。


另外,ASP.NET MVC 3 RTM Source Code都是使用C#撰寫,所以你必須有能看懂C#的能力。

使用Rzaor view engine

  1. CodePlex 下載 ASP.NET MVC 3 RTM Source Code,然後解壓縮。
  2. 在 Visual Studio 2010中,新增一個「ASP.NET MVC 3 Web 應用程式」專案(C#或Visual Basic都可)。
  3. 在 Visual Studio 2010 → 檔案 → 加入 → 現有專案 (由原始碼專案引用下列五個專案):System.Web.MVC (在 \mvc3-rtm-sources\mvc3\src 之下)、System.Web.Razor、System.Web.WebPages、System.Web.WebPages.Deployment、System.Web.WebPages.Razor (在 \mvc3-rtm-sources\webpages\src\ 之下)。

  4. 移除原System.Web.Mvc.dll參考。(在Visual Basic專案,必須先按「顯示所有檔案」才會出現「參考」資料夾,然後移除之)。

  5. 新增參考:在「參考」資料夾按右鍵 → 加入參考 → Projects → Solution → System.Web.Mvc。

  6. 按Ctrl + F5,執行專案,參考錯誤訊息。

    G:\Temp\VS\root\dc9d0955\1bea8b5d\App_Web_index.vbhtml.a8d08dba.0akkfrmq.0.vb(33) : error BC30560: 'WebViewPage' 在命名空間 'System.Web.Mvc' 中模稜兩可。
    
            Inherits System.Web.Mvc.WebViewPage
    
  7. 修改根目錄下Web.config,將<assemblies>區段中 System.Web.Mvc 及 System.Web.WebPages 的「Version, Culture, PublicKeyToken」三個值內容移除。<add assembly="System.Web.Mvc" /> <add assembly="System.Web.WebPages" />

    原始設定:
    <compilation debug="true" targetFramework="4.0">
          <assemblies>
            <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          </assemblies>
        </compilation>
    

    修改後設定:
    <compilation debug="true" targetFramework="4.0">
          <assemblies>
            <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Mvc" />
            <add assembly="System.Web.WebPages" />
          </assemblies>
        </compilation>
    
  8. 按Ctrl + F5再執行一次,參考錯誤訊息。

    System.InvalidCastException: [A]System.Web.WebPages.Razor.Configuration.HostSection 無法轉型為 [B]System.Web.WebPages.Razor.Configuration.HostSection. 型別 A 源自 'System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' 
    
  9. 修改 /Views/Web.config,將 <configSection>下的<configSections>區段所有Type值中的「Version, Culture, PublicKeyToken」三個值內容移除。將<configSection>下的<system.web.webpages.razor>下<host> 裡factoryType值中的「Version, Culture, PublicKeyToken」三個值內容移除。

    原始內容:
    <configSections>
        <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
          <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
          <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
        </sectionGroup>
      </configSections>
    
      <system.web.webPages.razor>
        <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <pages pageBaseType="System.Web.Mvc.WebViewPage">
          <namespaces>
            <add namespace="System.Web.Mvc" />
            <add namespace="System.Web.Mvc.Ajax" />
            <add namespace="System.Web.Mvc.Html" />
            <add namespace="System.Web.Routing" />
          </namespaces>
        </pages>
      </system.web.webPages.razor>
    

    修改後的內容:
    <configSections>
        <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor">
          <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor" requirePermission="false" />
          <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor" requirePermission="false" />
        </sectionGroup>
      </configSections>
    
      <system.web.webPages.razor>
        <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc" />
        <pages pageBaseType="System.Web.Mvc.WebViewPage">
          <namespaces>
            <add namespace="System.Web.Mvc" />
            <add namespace="System.Web.Mvc.Ajax" />
            <add namespace="System.Web.Mvc.Html" />
            <add namespace="System.Web.Routing" />
          </namespaces>
        </pages>
      </system.web.webPages.razor>
    
  10. 按Ctrl + F5再執行一次,你可以看到ASP.NET MVC 3專案已經順利執行,現在你已經可以使用ASP.NET MVC 3 RTM 原始碼在除錯模式中進行追蹤。


使用WebForm view engine (ASPX)


使用WebForm view engine (ASPX)步驟上差不多,都是

  1. 加入原始檔專案
  2. 移除System.Web.Mvc.dll
  3. 重新加入參考(只需引用一個)
  4. 修改相關Web.config設定

  1. 從 CodePlex 下載 ASP.NET MVC 3 RTM Source Code,然後解壓縮。
  2. 在 Visual Studio 2010中,新增一個「ASP.NET MVC 3 Web 應用程式」專案(C#或Visual Basic都可)。
  3. 在 Visual Studio 2010 → 檔案 → 加入 → 現有專案 (由原始碼專案引用一個專案):System.Web.MVC (在 \mvc3-rtm-sources\mvc3\src 之下)。
  4. 移除原System.Web.Mvc.dll參考。(在Visual Basic專案,必須先按「顯示所有檔案」才會出現「參考」資料夾,然後移除之)。
  5. 新增參考:在「參考」資料夾按右鍵 → 加入參考 → Projects → Solution → System.Web.Mvc。
  6. 修改根目錄下Web.config,將<assemblies>區段中 System.Web.Mvc 的「PublicKeyToken」的值修改為「null」內容移除。

    原始內容:
    <compilation debug="true" targetFramework="4.0">
          <assemblies>
            <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          </assemblies>
        </compilation>
    

    修改後的內容:
    <compilation debug="true" targetFramework="4.0">
          <assemblies>
            <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null" />
            <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          </assemblies>
        </compilation>
    
  7. 修改 /Views/Web.config,將 <System.Web>下的<Pages>區段所有含System.Web.Mvc值中的「PublicKeyToken」的值改為「null」(請注意,這裡與Razor不同)。

    原始內容:
    <pages
            validateRequest="false"
            pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
            pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
            userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
          <controls>
            <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
          </controls>
        </pages>
    

    修改後內容:
    <pages
            validateRequest="false"
            pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null"
            pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null"
            userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null">
          <controls>
            <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null" namespace="System.Web.Mvc" tagPrefix="mvc" />
          </controls>
        </pages>
    
  8. 重新建置,然後按 Ctrl+F5,就可以看到我們正常運作的ASP.NET MVC 3網頁。
  9. 設定中斷點。我們設定在HomeController.vb的「ViewData("Message") = "歡迎使用 ASP.NET MVC!"」這一行。
  10. 按下 F5。由「呼叫堆疊」來反追原始碼。



這樣我們就完成了ASP.NET MVC 3 RTM Source Code Tracing in Razor and ASPX的目的。

Web.config修改差異

如果你細心的話,可以看出,第一個方法是刪除「「Version, Culture, PublicKeyToken」三個值,第二個方法是修改「PublicKeyToken=null」,第二種方法在Razor也行。我這裡引用ASP.NET MVC 2 開發實戰」書中第328頁中的解譯:

由於Visual Studio 2010預設的ASP.NET MVC專案範本會加入註冊GAC的System.Web.Mvc組件參考,而註冊在GAC的組件都會設定公開金鑰語彙基元(PublicKeyToken),其內容是將組件或應用程式簽名時的公開金鑰,以SHA-1雜湊運算後取得最後8位元組。

自己加入的System.Web.Mvc組件參考到我們現有的ASP.NET MVC專案,所以,在Web.config如果載入System.Web.Mvc組件時,若有設定公開金鑰語彙基元的話,就會導致專案日的System.Web.Mvc組件與GAC裡面的System.Web.Mvc組件發生重複載入命名空間衝突的錯誤。
看沒(台),沒關係,這不影響我們學習ASP.NET MVC。記得,如果要使用ASP.MVC原始碼Debug,使用修改「PublicKeyToken=null」是比較快速的修改方式。

Reference:

沒有留言:

張貼留言

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。