接到任務,要在前人的專案新増一個小功能。由TFS下載原始碼準備編譯時,出現奇怪現象。
System.Web.Mvc參照失敗:
但System.Web.Razor及其他System.Web.*系列是好的:
同一專案在同事機器開啟一切正常。由於是參照問題,加上專案有點歷史,一度以為專案是因為最早使用Visual Studio 2012開發,System.Web.Mvc參照來自VS2012或另外安裝的ASP.NET MVC套件,而我的電腦沒裝過VS2012才出狀況。直到想起該檢查csproj,真相大白!
<Reference Include="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Razor.2.0.20710.0\lib\net40\System.Web.Razor.dll</HintPath>
</Reference>
…略…
<Reference Include="WebGrease">
<HintPath>..\..\packages\WebGrease.1.5.2\lib\WebGrease.dll</HintPath>
</Reference>
由csproj可知,不管System.Web.Mvc或System.Web.Razor都來自NuGet Packages,而我另外注意到,HintPath有..\packages及..\..\packages兩種,直接宣佈破案!而本宗案件需要綜合兩篇舊文章的知識:
- 【茶包射手日記】相同專案在另一台機器出現元件版本不合錯誤
剖析:問題專案搬過家,sln檔向上搬了一層目錄,packages理應也上搬一層,但csproj中部分HintPath仍指向原本的路徑,後來才用NuGet安裝的指向新路徑。同事電腦上仍留有搬家前的packages目錄,故可編譯無誤;我的原始碼取自TFS,NuGet還原時只會寫進.sln層的packages補足了程式庫,csprojq指向舊的packages路徑,導致Visual Stuio找不到System.Web.*。 - 【茶包射手日記】Visual Studio編譯成功的專案在IIS發生組件版本不合
剖析:既然System.Web.*都指錯地方,為什麼只有System.Web.Mvc參照出錯?這就不得不提「Visual Studio可以編譯IIS無法編譯專案」的特異功能(VS會額外搜索可能路徑)。在HintPath指錯的狀況下,VS2013努力補齊缺少的System.Web.*參照,獨漏System.Web.Mvc。
有了這次經驗,下回再有類似某幾個參照找不到的狀況,就不用傻找了,應依以下SOP處理:
- 優先確認csproj檔中的參照HintPath
- 若參照檔的屬性視窗與HintPath所指不符,請立即檢查是否路徑有誤或檔案遺失。