破解System.Web.Helpers 2.0.0.0與3.0.0.0之謎

破解System.Web.Helpers 2.0.0.0與3.0.0.0之謎

Error 2

System.Web.Helpers命名空間是.NET Framework裡一個神秘的組織,它和ASP.NET MVC 3一起推出,知道和用它的人並不多,它暗地裡提供許多便利型的功能(可以參考之前寫的系列文(12345678)。但如上圖所見,它在我VS2015裡的新專案裡就這樣赤裸裸的爆開,開啟著另一個VS2013的專案,怎麼一切安然無事。當下會很直覺的想罵聲-暗,是不是命中帶ㄕㄞˋ,老是碰到這種鬼錯誤。但有幾次VS2015的經驗,我改變心態,耐著性子一路追下去,意外發現System.Web.Helper一件不為人知的故事。

專案實況還原

以下我將用最簡化的方式來還原當時專案的狀況。

Helper專案

加入參考

我們有一個Helper專案,裡面有一個方法使用System.Web.Helpers.Crypto.SHA1()來進行加密動作。此Helper專案會讓其他專案進行使用。

  using System.Web.Helpers;

  namespace HelperSample
  {
      public class Signature
      {
          public static string Get(string token)
          {
              return Crypto.SHA1(token);
          }
      }
  } 
 

MVC專案

  1. 加入一個「Web - Empty - MVC 核心參考」的網站。
  2. 加入Helper專案參考。

呼叫Signature.Get()驗證功能是否正常。

  using HelperSample;
  using System.Web.Mvc;

  namespace MVCSample.Controllers
  {
      public class HomeController : Controller
      {
          // GET: Home
          public ActionResult Index()
          {
              ViewBag.SHA1 = Signature.Get("Bruce");
              return View();
          }
      }
  }  
 
MVC View

Very Good.

Web API專案

同MVC專案,我們再加入一個Web API專案。

  1. 加入一個「Web - Empty - Web API 核心參考」的服務專案。
  2. 加入Helper專案參考。

呼叫Signature.Get()驗證功能是否正常。

 using HelperSample;
 using System.Web.Http;

 namespace APISample.Controllers
 {
     public class CheckController : ApiController
     {
         public string Get()
         {
             return Signature.Get("Bruce");
         }
     }
 }  
 
FileNotFoundException

比對一下MVC專案與API專案的參考。

Check參考

從圖上來看,MVC專案有幫我們加入System.Web.Helpers的參考,API專案不列為核心參考也合情合理,就在API專案把System.Web.Helpers加上吧。

不過一啟動API服務就…

ErrorMessage 1
ErrorMessage 2

我不是明明加入了System.Web.Helpers的參考嗎?反覆看著錯誤訊息,是發現2.0.0.0與3.0.0.0問題,但怎麼會這樣呢?

API與Helper專案的System.Web.Helpers屬性

系統參考

MVC專案的System.Web.Helpers屬性

NuGet參考

為什麼MVC專案裡的是3.0.0.0的版本?

System.Web.Helpers 3.0.0.0之謎

上面最後兩張圖屬性圖,幾乎讓答案呼之欲出。比對兩張圖,除了版本號不同外,還就有就路徑不同。由系統參考的會指向C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies\System.Web.Helpers.dll這支DLL。但MVC專案是指向Z:\{project_path}\packages\Microsoft.AspNet.Webpages.3.2.3\lib\net45\System.Web.Helpers.dll

看到關鍵字了嗎?

原來,MVC中的System.Web.Helpers是由Microsoft ASP.NET Web Pages套件來提供。

那麼,API專案中,我明明已經加入系統參考2.0.0.0版本,它怎麼那麼聰明的知道有個3.0.0.0版本,而且我還不用不行呢?

Assembly Redirect

感謝好友Dino Wang提供Assembly Redirect明燈。

在前述的錯誤訊息裡有一句:

記錄: 在應用程式組態檔中找到重新導向: 重新導向 2.0.0.0 至 3.0.0.0。

開啟API專案的Web.config(明年我就會想念它了):

Assembly Redirect

這樣的設置與系統給出的錯誤訊息是相吻合的。茶包,你就安心走吧。

要讓API專案能正常運作,就要安裝Microsoft.AspNet.WebPages套件。

如果想玩玩可重視環境,這裡有GitHub範例專案:SystemWebHelperTrace

沒有留言:

張貼留言

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