首頁  >  文章  >  後端開發  >  剖析Asp.Net Web API路由系统---WebHost部署方式

剖析Asp.Net Web API路由系统---WebHost部署方式

高洛峰
高洛峰原創
2017-02-20 17:04:201480瀏覽

上一篇我們剖析了Asp.Net路由系統,今天我們再來簡單剖析一下Asp.Net Web API以WebHost方式部署時,Asp.Net Web API的路由系統內部是怎樣實現的。還是以一個簡單實例開頭。

建立一個空的WebApi項目,在Global中註冊路由資訊:

  public class WebApiApplication : System.Web.HttpApplication
  {
    protected void Application_Start()
    {
      //注册路由
      GlobalConfiguration.Configuration.Routes.MapHttpRoute(
        name: "default",
        routeTemplate: "api/{controller}/{id}", 
        defaults: new { id = RouteParameter.Optional });
    }
  }

建立一個名為Home的Controller:

  public class HomeController : ApiController
  {
    // GET: api/Home
    public IEnumerable<string> Get()
    {
      return new string[] { "value1", "value2" };
    }

    // GET: api/Home/5
    public string Get(int id)
    {
      return "value";
    }
    
  }

啟動運行,在瀏覽器網址列分別輸入http://localhost:46351/api/home和http://localhost:46351/api /home/5,結果如下:

 

剖析Asp.Net Web API路由系统---WebHost部署方式

簡單看了一下Asp.Net Web API的實例,下面我們開始剖析Asp.Net Web API的路由系統。

首先看一下在Asp.Net Web API中路由的註冊方式,如下:

 剖析Asp.Net Web API路由系统---WebHost部署方式

在這個路由註冊過程中,隱藏了哪些操作呢?下面我們原始碼:

剖析Asp.Net Web API路由系统---WebHost部署方式

剖析Asp.Net Web API路由系统---WebHost部署方式

剖析Asp.Net Web API路由系统---WebHost部署方式

剖析Asp.Net Web API路由系统---WebHost部署方式 

透過翻閱原始碼可以看到,Asp.Net Web API中路由的註冊實際上是透過呼叫HttpRouteCollection類型的擴充方法MapHttpRoute實現的,在MapHttpRoute方法裡面,我們看到建立的路由物件透過呼叫HttpRouteCollection物件的Add方法保存了。而由於GlobalConfiguration的靜態屬性透過Configuration是HostedHttpRouteCollection類型以RouteTable.Routes為建構參數建立的,又因為HostedHttpRouteCollection類型是HttpRouteCollection類型的子類,在HostedHttpRouteCollection類型是HttpRouteCollection類型的子類,在HostedHttpRouteCollection類型中,且HouteHot.方法,如下圖,所以,實際上創建出來的路由物件的類型為HostedHttpRoute,此路由物件放到全域路由表中保存了,從這裡我們可以知道,保存到全域路由表中的路由物件的類型為HostedHttpRoute 。那麼,註冊的路由物件放到全域路由表中保存有什麼用呢,後續部分分析。

剖析Asp.Net Web API路由系统---WebHost部署方式

剖析Asp.Net Web API路由系统---WebHost部署方式 

從上面源碼可以看到,最後創建的路由對像是HostedHttpRoute類型,那麼現在有個問題,我們在前面註冊路由的時候,並沒有指定RouteHandler和HttpHandler,它們是從哪裡加入到路由物件中的呢?在創建HostedHttpRoute物件的過程中,又有哪些隱藏的秘密呢?我們下面繼續查看原始碼:

剖析Asp.Net Web API路由系统---WebHost部署方式

剖析Asp.Net Web API路由系统---WebHost部署方式 

透過上文的剖析,到目前為止,我們可以知道在Asp.Net Web API以WebHost方式寄宿時,註冊的路由物件為HostedHttpRoute類型的實例,保存在全域路由表RouteTable.Routes中,而用於處理請求的RouteHandler和HttpHandler分別為HttpControllerRouteHandler類型的實例和HttpControllerHandler類型的實例。

 註冊完路由資訊後,在Asp.Net Web API中是如何利用註冊的路由資訊進行路由的呢?會不會也是跟Asp.Net中一樣透過一個HttpModule來實現的呢,我們啟動程式看一下Global類別中的Modules屬性:

 剖析Asp.Net Web API路由系统---WebHost部署方式

從上面截圖可以清楚看到,當Asp.Net Web API以WebHost方式寄宿服務時,也是跟ASP.Net一樣,透過UrlRoutingModule來實現路由的。從上一篇針對Asp.Net路由系統的剖析中,我們可以知道,Asp.Net是透過UrlRoutingModule對請求進行攔截後,然後從全域路由表中依序進行比對以取得與請求Url相符的RouteData進行後續處理的。在Asp.Net Web API中,從上文我們知道了保存在全域路由表的路由物件是HostedHttpRoute類型的,下面我們繼續剖析在Asp.Net Web API中最終是怎麼獲取到匹配的RouteData的。

在UrlRoutingModule中,RouteData是透過依序呼叫每個路由物件的GetRouteData方法取得的。在Asp.Net Web API中,由於路由物件的類型為HostedHttpRoute,下面我們來看看呼叫GetRouteData方法時發生了什麼:

剖析Asp.Net Web API路由系统---WebHost部署方式 

可以看到,在HostedHttpRoute中是透過屬性OriginalRoute的GetRouteData方法取得RouteData的,由前文的剖析中,我們知道這個OriginalRoute屬性是HttpWebRoute類型:

剖析Asp.Net Web API路由系统---WebHost部署方式

剖析Asp.Net Web API路由系统---WebHost部署方式 

 從上面剖析中可以看到,Asp.Net Web API以WebHost方式部署時,最終還是透過Asp.Net的路由系統完成配對工作。不過有一定要注意的是,由於在HttpWebRoute中對父類型的驗證約束的方法進行了重寫,所以對於約束的驗證,Asp.Net Web API還是使用了自己的方式進行驗證約束是否匹配:

剖析Asp.Net Web API路由系统---WebHost部署方式

最後,透過一系列的工作取得到了RouteData物件和包含在裡面的RouteHandler、HttpHandler後,Asp.Net Web API就可以透過這些取得到的進行請求的處理和響應了。

 總結:

透過上文的剖析,可以得出:在Asp.Net Web API以WebHost方式部署時,註冊的路由是保存在全域路由表中的;在取得RouteData時,是透過Asp.Net路由系統的符合規則進行路由比對的,不過卻實作了自己的約束驗證規則。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持PHP中文網。

更多剖析Asp.Net Web API路由系統---WebHost部署方式相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn