ASP.NET Web API - ASP.NET MVC 4 系列

       Web API 項目是 Windows 通訊接口(Windows Communication Foundation,WCF)團隊及其用戶激情下的產物,他們想與 HTTP 深度整合。WCF 進行 Web 服務編程的迭代是一個抽象事務,主要爲了隱藏像傳輸細節同樣的內容。Web API 試圖完全顛覆這一過程,去掉 WCF 中的大部分層,而容許開發人員直接訪問 HTTP 編程模型的全部方面。編程

       ASP.NET MVC 在接收表單數據生成 HTML 方面功能很是強大;ASP.NET Web API 在接收和生成像 JSON 和 XML 等結構化數據方面功能很是強大api

       因爲 ASP.NET Web API 是另外一個全新的框架,本文主要介紹 MVC 和 Web API 之間的異同,以幫助你們決定是否在 MVC 項目中使用 Web API。數組

 

 

編寫 API 控制器

       使用 Web API 模板添加一個項目,這個模板是惟一一個包含示例 API 控制器的模板。服務器

       Web API 和 MVC 都利用了控制器,它們都擁有將 HTTP 請求映射成控制器操做的概念,但不是使用輸出模板和視圖引擎渲染結果的 MVC 模式,Web API 直接把結果模型對象做爲響應來渲染。app

       查看先前模板生成的 Web API 類:框架

public class ValuesController : ApiController
{
    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
 
    // GET api/values/5
    public string Get(int id)
    {
        return "value";
    }
 
    public void Post([FromBody]string value)
    {
    }
 
    // PUT api/values/5
    public void Put(int id, [FromBody]string value)
    // POST api/values
    {
    }
 
    // DELETE api/values/5
    public void Delete(int id)
    {
    }
}

       這個控制器類和 MVC 模式下的控制器類有如下區別:異步

  1. 它繼承自 ApiController 類。
  2. 控制器中的方法返回的是原始對象,而不是視圖,也不是其餘輔助操做對象。
  3. MVC 控制器老是根據名稱調度操做,Web API 控制器默認根據 HTTP 動詞調度操做。

異步設計:IHttpController

       image

       查看 ApiController,若是與 MVC 的Controller 對比,會發現其中一些概念是相同的,好比控制器上下文、ModelState、Url 輔助方法和 User。但一些概念類似卻存在差別,好比 Request 是來自 System.Net.Http 的 HttpRequestMessage 而不是來自 System.Web 的 HttpRequestBase,一些概念是缺失的,好比最顯著的 Response 和 ActionResult 的生成方法。ide

       ApiController 中的 ExecuteAsync 方法是接口 IHttpController 中的方法,顧名思義,它意味着全部 Web API 控制器都是異步設計。這裏的管道不一樣於 ASP.NET,所以也不能訪問 Response 對象。函數

       API 控制器指望返回一個 HttpRequestMessage 類型的對象。HttpRequestMessage 和 HttpResponseMessage 類構成了 System.Net.Http 中 HTTP 支持的基礎。這些類的設計不一樣於 ASP.NET 的核心運行時類,在這個棧的處理方法中,給定一個請求消息,指望返回一個響應消息。System.Net.Http 沒有靜態方法訪問持續請求的信息,這也意味着,沒必要直接寫入響應流,開發人員能夠返回一個描述響應的對象,而後在須要時渲染單元測試

傳入的操做參數

       爲從請求中接收傳入的值,可在操做上放置參數,就像 MVC 同樣,Web API 框架會自動爲這些操做方法提供參數值。不一樣的是,從 HTTP 主體獲取的值和從其餘地方(好比 URI)獲取的值之間有一條強線strong line)。

       默認狀況下,Web API 會假設簡單類型(如字符串、日期、時間)的參數是非主體值,而複合類型從主體獲取。此外,還有一個額外的限制:只有一個值能夠來自主體,而且這個值必須表明整個主體。

       若是傳入參數不是主體的一部分,就會由模型綁定系統處理,這裏的模型綁定系統與 MVC 的類似。另外一方面,傳入和輸出的主體會被一個「格式器」處理

操做返回值、錯誤和異步

       Web API 控制器以操做返回值的方式把值發回客戶端,然而,返回響應對象是一個至關低級的操做,因此 Web API 控制器幾乎老是返回一個原始對象值或值序列。當操做返回一個原始對象時,Web API 使用稱爲內容協商(Content Negotiation)的功能把它自動轉換成一個符合要求的結構化響應,好比 JSON 和 XML。

配置 Web API

       可能極想知道控制器上的 Configuration 屬性。在傳統 ASP.NET 應用程序中,應用程序配置在 Global.asax 中完成,應用程序使用全局狀態(包括靜態的和線程局部變量)訪問請求和應用程序配置。

       Web API 被設計爲不具備任何這樣的靜態全局值,而把它的配置放在 HttpConfiguration 類中。這對應用程序有兩方面影響:第一,可在一個應用程序中運行多個 Web API 服務器,由於每一個服務器有它自身的非全局配置;第二,可在 Web API 中更方便的運行單元測試和端到端測試。

       配置類能夠訪問下列項:

  • 路由
  • 爲全部請求運行的過濾器
  • 參數綁定規則
  • 讀寫主體內容使用的默認格式器
  • Web API 使用的默認服務
  • 用戶提供的依賴解析器(針對服務和控制器上的 DI)
  • HTTP 消息處理程序
  • 標記是否包含像堆棧跟蹤這樣的錯誤細節
  • 能夠存放用戶定義值的 Properties 袋

       建立和訪問這些配置的方式取決於咱們如何託管應用程序:在 ASP.NET 內,仍是在 WCF 自託管內。

Web 託管 Web API 的配置

       Web API 的配置代碼在文件 WebApiConfig.cs 中,開發人員能夠修改這個文件以知足本身應用程序的要求,默認代碼僅包含一個路由示例

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

       若是查看 Global.asax 文件,會發現這個函數經過傳進 GlobalConfiguration.Configuration 對象來調用,Web 託管的 Web API 僅支持單一服務器和單一配置文件

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
 
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

       GlobalConfiguration 類在程序集 System.Web.Http.WebHost.dll 中,它是基礎設施的其他部分,用來支持 Web 託管的 Web API

自託管的 Web API

       與 Web API 一塊兒發佈的其餘託管是基於 WCF 的自託管。自託管的代碼包含在程序集 System.Web.Http.SelfHost.dll 中。

       沒有針對自託管的內置項目模板,由於這樣沒有項目類型限制,當須要使用自託管時,咱們就可使用。咱們可能正託管在一個控制檯應用程序中,或者在一個 GUI 應用程序內部,甚至在一個 Windows 服務中。

       當使用自託管時,須要正確的建立配置,啓動和中止 Web API 服務器。咱們須要實例化的配置類是 HttpSelfHostConfiguration,由於它經過要求一個監聽的 URL 擴展了基類 HttpConfiguration,正確配置好以後,就會建立一個 HttpSelfHostServer 實例,而後告訴它開始監聽。

       下面是自託管啓動代碼的一個示例片斷:

var config = new HttpSelfHostConfiguration("http://localhost:8080/");
 
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
 
var server = new HttpSelfHostServer(config);
server.OpenAsync().Wait();
 
完成以後,應該關閉服務器:
server.CloseAsync().Wait();

       若是在控制檯應用程序中是自託管,咱們應該在 Main 函數中運行這些代碼,對於其餘應用程序類型的自託管,只須要找到合適位置以運行應用程序的啓動和關閉代碼便可。

       Web API 的託管系統是可插拔的,這些託管配置獨立於託管系統

向 Web API 添加路由

       Web API 的主要路由註冊是 MapHttpRoute 擴展方法,與全部 Web API 配置任務同樣,爲應用程序的路由配置了 HttpConfiguration 對象。Routes 屬性指向 HttpRouteCollection 類的一個實例,而不是 ASP.NET 的 RouteCollection 類實例。Web API 提供了一些直接依賴 ASP.NET 中 RouteCollection 類的 MapHttpRoute 版本,但這些路由只有在自託管時才能使用。爲避免 Web API 擁有 ASP.NET 的硬依賴,開發團隊採用了 ASP.NET 路由代碼的副本並加以修改,把它移植到 Web API,當在自託管環境中運行,Web API 會使用它本身的私有路由代碼副本;當應用程序是 Web 託管時,Web API 會使用 ASP.NET 的內置路由引擎,由於它已經鏈接到了 ASP.NET 請求管道。此時,系統就不僅會註冊 HttpRoute 對象,也會自動建立封裝 Route 對象,並在 ASP.NET 路由引擎中註冊這些對象。

      自託管和 Web 託管之間的主要區別在於路由的運轉時刻:對於 Web 託管,ASP.NET 運行路由很是早;但在自託管中,Web API 運行路由的時刻就很是晚,若是編寫消息處理程序,知道可能沒法訪問路由信息是很重要的,由於此時路由可能還沒有運行。

       image

綁定參數

       當編寫操做方法簽名時,來自主體的複雜類型由格式器負責生成;來自非主體的簡單類型由模型綁定器負責生成。

       這裏提出一個 Web API 的新概念:參數綁定Web API 使用參數綁定器來決定如何爲各個參數提供值。特性能夠用來影響這個決定,好比 MVC 中的特性 [ModelBinder],但當沒有重寫方法影響綁定決定時,默認的邏輯使用簡單類型和複合類型。參數綁定系統經過查看操做參數,尋找 ParameterBindingAttribute 派生的屬性。Web API 中建立有一些這樣的特性,以下表,此外,還能夠經過在配置文件中註冊或者經過編寫基於 ParameterBindingAttribute 的特性,來註冊不使用模型綁定器和格式器的自定義參數綁定器。

特  性

描  述

ModelBindingAttribute 該特性告訴參數綁定系統使用模型綁定,也就是經過使用註冊模型綁定器和值提供器建立值。

這就是經過簡單類型參數的默認綁定邏輯表示的內容。
FromUriAttribute 該特性是一個專門的 ModelBindingAttribute,它告訴系統只能使用實現了 IUriValueProviderFactory 的值提供器,從而限制值的範圍,確保它們只能從 URI 獲取。

開箱即用,路由數據和 Web API 中的查詢字符串值提供器實現了這個接口。
FromBodyAttribute 該特性告訴參數綁定系統使用格式器,也就是經過查找 MediaTypeFormatter 的實現建立值,這裏的 MediaTypeFormatter 能夠解碼主體,從解碼主體數據中建立給定類型。

這就是經過任何複合類型的默認綁定邏輯表示的內容。

       在 MVC 中,全部參數都是經過模型綁定建立,而 Web API 模型綁定的工做方式與 MVC(模型綁定器和提供器,值提供器和工廠)幾乎同樣,儘管它稍微重構了基於 MVC Futures 中的備用模型綁定系統。針對數組、集合、字典、簡單類型甚至複合類型,咱們會發現有對應的內置模型綁定器,儘管須要使用特性 [ModelBinder] 來運行這些綁定器。雖然接口有輕微改動,但若是知道如何在 MVC 中編寫模型綁定器和值提供器,那麼也能爲 Web API 作一樣的事。

       格式器是 Web API 的新概念。格式器主要負責使用和生成主體內容。能夠把它想象成 .NET 中的序列化器(serializers):負責編碼和解碼,能夠把一個對象精確編碼到主體,也能夠從主體中精確解碼一個對象,對象能夠包含嵌套對象

       Web API 內部有三種格式器:

  1. 使用 Json.NET 編碼和解碼 JSON
  2. 使用 DataContractSerializer 編碼和解碼 XML
  3. 另外一種解碼錶單 URL,編碼主體數據
相關文章
相關標籤/搜索