﻿# 如何正確建置 ASP.NET MVC 5 原始碼並對原始碼進行分析研究

上次寫[這個主題](/post/2009/02/08/ASPNET-MVC-Developer-Note-Part-2)已經是 2009/2/8 的事情了，原來我已經用 ASP.NET MVC 寫了超過 12 年。時至今日 ASP.NET MVC 5 已經非常穩定，而且微軟還有團隊在維護這套框架，但不會增加新功能，只會修正社群回報的 Bug 而已。由於最近正在進行 ASP.NET MVC 5 開發實戰課程，我也非常建議學員可以下載原始碼回來研究，所以這篇文章我將說明下載原始碼編譯的幾個重要步驟。

### 準備能夠成功建置 ASP.NET MVC 5 原始碼的基本環境

1.  下載 .NET Core 2.1 SDK
    
    目前最新版的 [.NET Core 2.1 SDK](https://dotnet.microsoft.com/download/dotnet/2.1?WT.mc_id=DT-MVP-4015686) 有分兩個版本，分別是支援 Visual Studio 2017 的 [v2.1.524](https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-2.1.524-windows-x64-installer) 版本，以及支援 Visual Studio 2019 的 [v2.1.816](https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-2.1.816-windows-x64-installer) 版本。
    
    🔥 請務必安裝支援 **Visual Studio 2017** 的 `.NET Core 2.1 SDK` 版本！
    
    以下是快速自動安裝的 PowerShell 命令：
    
    ```powershell
    Invoke-WebRequest https://download.visualstudio.microsoft.com/download/pr/c72a8b51-d3ef-4900-b950-55c9707c63d3/76948b5f23d012affb30f2cc24d3131e/dotnet-sdk-2.1.524-win-x64.exe -outfile $env:temp\dotnet-sdk-2.1.524-win-x64.exe
    Start-Process $env:temp\dotnet-sdk-2.1.524-win-x64.exe -ArgumentList '/quiet' -Wait
    ```
    
2.  安裝 Visual Studio 2017 建置工具
    
    安裝 [Visual Studio 2017 Build Tools](https://community.chocolatey.org/packages/visualstudio2017buildtools) 與 [.NET Core build tools workload for Visual Studio 2017 Build Tools](https://community.chocolatey.org/packages/visualstudio2017-workload-netcorebuildtools) 這兩個 Chocolatey 套件即可。
    
    ```powershell
    choco install visualstudio2017buildtools visualstudio2017-workload-netcorebuildtools -y
    ```
    

### 下載原始碼並編譯專案

目前最新版 ASP.NET MVC 原始碼都放在 [aspnet/AspNetWebStack](https://github.com/aspnet/AspNetWebStack) 這個 GitHub Repo 下，但事實上這個是一個蠻大的專案，其原始碼涵蓋了 ASP.NET MVC 5.x, Web API 2.x, 與 Web Pages 3.x 等框架，其中還包含了許多**範例程式**與**單元測試**程式碼，非常具有參考價值，也是個非常棒的學習資源！

1.  下載最新版 ASP.NET MVC 原始碼 (僅下載 `v3.2.7` 版本的原始碼)
    
    ```powershell
    git clone https://github.com/aspnet/AspNetWebStack.git -b v3.2.7 --depth=1
    cd AspNetWebStack
    ```
    
    > 注意：使用 `--depth=1` 只會下載指定分支/標籤下最新一個版本的 Git 物件，下載速度極快，但看不到其他歷史版本！
    
2.  檢查原始碼中的 `global.json` 檔案中的 .NET Core SDK 版本
    
    請手動修改該檔案的 `version` 屬性，改成你剛剛安裝的 .NET Core 2.1 SDK 版本 (Visual Studio 2017)
    
    ```json
    {
        "sdk": {
            "version": "2.1.524"
        }
    }
    ```
    
3.  建置專案
    
    由於 GitHub Repo 上面並沒有說明如何建置該專案，基本上建議你用以下命令建置，成功率將會大增！
    
    ```powershell
    build.cmd Build /p:BuildPortable=false
    ```
    
4.  執行所有的 xUnit 單元測試程式
    
    先執行 `EnableSkipStrongNames` 目標，否則你將無法成功執行 xUnit 測試程式
    
    ```powershell
    build.cmd EnableSkipStrongNames
    ```
    
    直接執行 `build.cmd` 命令即可開始跑所有測試
    
    ```powershell
    build.cmd
    ```
    
    > 我有發現 [GenerateTokenHtmlEncodesValues()](https://github.com/aspnet/AspNetWebStack/blob/v3.2.7/test/WebMatrix.WebData.Test/SimpleMembershipProviderTest.cs#L167-L181) 測試方法在我的電腦無法成功通過單元測試，不太確定是什麼問題。我有開一個 [Issue #301](https://github.com/aspnet/AspNetWebStack/issues/301) 追蹤這個問題。如果要通過這個測試，可以暫時手動跳過這個測試，只要在 `[Fact]` 改成 `[Fact(Skip = "Might be a bug")]` 即可。
    

### 使用 Visual Studio 2019 分析 ASP.NET MVC 5 原始碼的技巧

如果你想直接以 Visual Studio 2019 開啟專案，請開啟 `Runtime.sln` 方案檔進行建置。

開啟方案總管即可看到所有 ASP.NET Web Stack 的所有原始碼：

![Runtime](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/9df7ea04c50b3e5c99f3-126041695-4d07f368-a32c-48f4-b947-d7d5ef39572d.png)

以下我分享幾個查找原始碼的技巧：

1.  善用 `Ctrl+,` 快速查找檔案
    
    ![快速查找檔案](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/20533ffe41ffc08f8cc1-126042174-9f7a0a91-2443-4472-b074-fefd08b8df12.jpg)
    
2.  善用 **與使用中文件同步處理** 功能快速開啟檔案在**方案總管**中的位置
    
    ![Sync with Active Document](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/11766eb15b9db45bac47-126042216-b7d2db70-6f31-49e9-9b9c-2013d12249b8.jpg)
    
3.  善用**方案總管**去尋找一個**抽象類別**的**衍生類型**(Derived Types)/**實作者**(Implements) (超級實用!)
    
    ![善用方案總管去尋找一個抽象類別的衍生類型](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/72c2b794bb17d3be182e-126042311-0bf3afd7-06de-49e7-b55a-e49152dc96e8.jpg)
    
    ![方案總管 / 衍生類型](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/f992986f068ab50f3b23-126042449-0be74e2c-5480-4a70-8109-d52cff97a43a.jpg)
    
4.  尋找 ASP.NET MVC 應用程式的啟動點：`MvcHandler`
    
    ASP.NET MVC 5 框架其實是一個 `IHttpHandler` 的實作，所以你要找到一個名為 `MvcHandler` 的類別，裡面有個 `IHttpHandler.ProcessRequest(HttpContext httpContext)` 方法，就是整個 ASP.NET MVC 5 的啟始點，從這裡開始看程式，你將會發現許多鮮為人知的寶貝與程式寫法！ 👍
    

### 相關連結

-   [aspnet/AspNetWebStack: ASP.NET MVC 5.x, Web API 2.x, and Web Pages 3.x (not ASP.NET Core)](https://github.com/aspnet/AspNetWebStack)
-   [ASP.NET MVC / Web API / Web Pages - CodePlex Archive](https://archive.codeplex.com/?p=aspnetwebstack)
