程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Asp.Net WebApi核心對象解析(上篇),asp.netwebapi

Asp.Net WebApi核心對象解析(上篇),asp.netwebapi

編輯:關於.NET

Asp.Net WebApi核心對象解析(上篇),asp.netwebapi


   生活需要自己慢慢去體驗和思考,對於知識也是如此。匆匆忙忙的生活,讓人不知道自己一天到晚都在干些什麼,似乎每天都在忙,但又好似不知道自己到底在忙些什麼。不過也無所謂,只要我們知道最後想要什麼就行。不管怎麼樣,我們還是得學習,讓自己不斷的向前,這樣才可以漸漸看到自己的追求,發發感歎,誰讓樓主以前是寫小說的呢(想看樓主以前的小說可以私聊我,以前絕對貨真價實的文藝青年,可惜現在已經是屌絲了。)

   不扯淡,還是來聊正經事,什麼正經事勒?對於程序員來說,當然代碼才是正經事了。

   在我們的項目開發中,很多時候需要使用到多系統的數據交互,以及一些功能的分布式開發。在.NET的體系中的分布式技術主要有webservice,.net remoting,MSMQ,WCF等等,但是今天介紹的是Asp.Net WebApi,對於Asp.Net WebApi技術,估計很多人都不會陌生,或者經常使用,因為對於其他的分布式技術的問題,在使用的時候會比較的繁瑣,但是Asp.Net WebApi可能會簡便和快捷很多。下面具體介紹一下Asp.Net WebApi技術。

一.WebApi概述:

    ASP.NET Web API是在.NET Framework之上構建的Web的API的框架,ASP.NET Web API是一個編程接口,用於操作可通過標准HTTP方法和標頭訪問的系統,ASP.NET Web API需要基於.NET 3.5或更高版本才可以進行開發。我們在學習ASP.NET Web API時,需要對HTTP協議、web知識有一個比較深入的認識,這樣在學習ASP.NET Web API時會比較快速的上手和應用。這裡就不介紹HTTP協議和Web相關的基礎知識,需要了解的可以自行百度搜索學習。

   ASP.NET Web API可提供各種HTTP客戶端使用,可以使用web基礎設施提供的服務。

   1.ASP.NET Web API具有以下的幾個特點:

      (1).可供多種客戶端使用。

      (2).支持標准的HTTP方法。

      (3).支持浏覽器友好的格式。(支持浏覽器以及任何其它HTTP客戶端容易支持的格式,例如json,xml等數據格式)

      (4).支持浏覽器友好的認證方式。

   2.ASP.NET Web API所需的軟件包:

      (1).System.Net.Http:提供核心HTTP編程模型。

      (2).System.AspNet.WebApi:提供在ASP.NET中安裝和托管所需的安裝的所有軟件包的一個引用。

      (3).System.AspNet.WebApi.Core:包含核心WebApi編程模型和運行時組件。

      (4).System.AspNet.WebApi.Client:包含核心.NET HTTP客戶端庫的擴展。

      (5).System.AspNet.WebApi.WebHost:包含在ASP.NET運行時中托管WebApi所需的全部運行時組件。

   對於ASP.NET Web API的簡單demo、安全認證、異常處理、內容協商、寄宿方式、錯誤處理等等,在這裡就不再過於介紹,如果有時間博主會單獨講解這些內容。

二.WebApi路由機制的簡要概述:

    對於ASP.NET Web API路由的介紹會比較簡單,因為對於熟悉asp.net mvc的人來說不是什麼難事,而且本次博文的重點並不是在這裡,所以在這裡只會做一個簡單的介紹。ASP.NET WebAPI使用HTTP方法,而不是URI路徑,以此來選擇動作。還可以使用MVC樣式路由的WebAPI。

    在ASP.NET Web API中,一個控制器是處理HTTP請求的類。控制器的公共方法被稱為動作方法或簡單的動作。當Web API框架接收到一個請求,它請求路由到一個動作。要確定調用哪個動作,框架使用的路由表。如下代碼:

routes.MapHttpRoute(
    name: "API Default",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

    我們在設置WebAPI路由時,已盡量注意與AspNet Mvc的路由發生沖突,這一點在ASP.NET Web API中做了一個防范。

    ASP.NET Web API的路由運行機制如下:

      (1).找到控制器,網絡API將“控制器”的值 {}控制變量。

      (2).查找的動作,網絡API著眼於HTTP方法,然後尋找一個動作名稱以該HTTP方法名。例如,用GET請求,WebAPI查找與“獲取...”,例如“GetContact”或“GetAllContacts”開頭的動作。該公約只適用於GET,POST,PUT和DELETE方法。您可以通過使用控制器上的屬性啟用其他HTTP方法。

      (3).在路由模板其他占位符變量,諸如{ID},被映射到動作的參數。

   對於ASP.NET Web API的路由機制就講解這麼多,更多的內容大家可以自己去了解。

三.WebApi核心對象ApiController:

    在我們的asp.net webapi項目中,在頂層目錄App_Start下,有一個WebApiConfig類,該類只包含一個方法Register,由Global.asax中的Application_Start方法調用代碼,如下代碼:

 GlobalConfiguration.Configure(WebApiConfig.Register);

    路由的映射方法只是一個擴展方法,如果需要了解“擴展方法”的相關知識,可以閱讀以下:http://www.cnblogs.com/pengze0902/p/6110094.html,在這裡就做介紹了,創建一個路由實例,並把這個實例添加到與宿主相關的路由集合之中。

    現在這裡著重介紹一下ApiController類。

    ApiController是ValuesController類的父類,是整個ASP.NET Web API的核心類,繼承該類可以用來創建ASP.NET Web API控制器。ApiController類中的公共靜態(在Visual Basic中共享)成員是線程安全的,任何實例成員都不能保證是線程安全的。下面介紹一下ApiController在ASP.NET Web API中所承擔的任務如下:

  (1).選擇和運行控制器類上的一個操作方法。

  (2).將HTTP請求消息的各元素轉換成控制器操作方法的參數,並將操作方法的返回值轉換為有效的HTTP響應正文。(HTTP響應body的數據格式可以客戶端和服務器進行協商,默認為json格式,對於json格式的好處,在這裡就不做介紹,但是個人覺得json格式應該會成為以後數據格式的重心。)

  (3).運行各種篩選器,這些篩選器可以是為操作方法或控制器配置,也可以是全局的。

  (4).為控制器類的操作方法提供適當的上下文狀態。

    以上是ApiController類的作用的簡單介紹,下面我們具體看一下實現代碼。

    首先,我們先來預覽一下ApiController類的方法和屬性:  

      1.屬性摘要:

         ActionContext:獲取操作上下文;

         Configuration和ControllerContext:獲取當前 ApiController 的 HttpConfiguration對象;

         ModelState:在模型綁定過程之後獲取模型狀態;

         Request:獲取或設置當前 ApiController 的 HttpRequestMessage;

         RequestContext: 獲取請求上下文;

         Url:用於生成指向其他 API 的 URL;

         User:返回與此請求關聯的當前主體;

      2.方法摘要:

         ExecuteAsync(): 異步執行單個 HTTP 操作,該方法為虛方法,可在子類中重寫;

         Validate<TEntity>():驗證給定實體並使用空前綴將驗證錯誤添加到模型狀態;

         Initialize():使用指定的 controllerContext 初始化 System.Web.Http.ApiController 實例;

         BadRequest():創建具有指定的InvalidModelStateResult模型狀態。

         Created():創建一個CreatedNegotiatedContentResult`1(201表示已創建)具有指定的值。

         Redirect():創建具有指定值的重定向結果(302 Found)。

         ResponseMessage():創建具有指定響應的ResponseMessageResult。

      3.詳細代碼介紹:

        ApiController類實現了IHttpController和IDisposable接口。在ASP.NET Web API中如果需要創建控制器,只需要實現IHttpController接口即可,我們看一下IHttpController接口的實現代碼:   

    //表示 HTTP 控制器
    public interface IHttpController
    {
        // 執行用於同步的控制器。
        //參數:controllerContext:測試控制器的當前上下文。cancellationToken:取消操作的通知。
        //返回結果:控制器。
        Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken);
    }

      可以看到該接口只有一個方法ExecuteAsync(),該方法為一個異步方法,HttpControllerContext表示一個HTTP請求對象,CancellationToken表示一個傳遞一個消息,為HTTP操作分配的取消令牌,Task<HttpResponseMessage>可以看出該方法返回一個異步的HTTP對象。我們看一下ApiController類中隊該類的實現代碼:

     /// <summary>
    /// 異步執行單個 HTTP 操作。
    /// </summary>
    /// <returns>
    /// 新啟動的任務。
    /// </returns>
    /// <param name="controllerContext">單個 HTTP 操作的控制器上下文。</param><param name="cancellationToken">為 HTTP 操作分配的取消標記。</param>
    public virtual Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
    {
      if (this._initialized)
        throw Error.InvalidOperation(SRResources.CannotSupportSingletonInstance, new object[2]
        {
          (object) typeof (ApiController).Name,
          (object) typeof (IHttpControllerActivator).Name
        });
      this.Initialize(controllerContext);
      if (this.Request != null)
        HttpRequestMessageExtensions.RegisterForDispose(this.Request, (IDisposable) this);
      ServicesContainer services = controllerContext.ControllerDescriptor.Configuration.Services;
//根據HTTP請求內容選擇動作 HttpActionDescriptor actionDescriptor = ServicesExtensions.GetActionSelector(services).SelectAction(controllerContext); this.ActionContext.ActionDescriptor = actionDescriptor; if (this.Request != null) HttpRequestMessageExtensions.SetActionDescriptor(this.Request, actionDescriptor); FilterGrouping filterGrouping = actionDescriptor.GetFilterGrouping();
//獲取動作過濾器 IActionFilter[] actionFilters = filterGrouping.ActionFilters;
//獲取授權過濾器 IAuthenticationFilter[] authenticationFilters = filterGrouping.AuthenticationFilters; IAuthorizationFilter[] authorizationFilters = filterGrouping.AuthorizationFilters;
//獲取異常過濾器 IExceptionFilter[] exceptionFilters = filterGrouping.ExceptionFilters; IHttpActionResult innerResult = (IHttpActionResult) new ActionFilterResult(actionDescriptor.ActionBinding, this.ActionContext, services, actionFilters); if (authorizationFilters.Length > 0) innerResult = (IHttpActionResult) new AuthorizationFilterResult(this.ActionContext, authorizationFilters, innerResult); if (authenticationFilters.Length > 0) innerResult = (IHttpActionResult) new AuthenticationFilterResult(this.ActionContext, this, authenticationFilters, innerResult); if (exceptionFilters.Length > 0) { IExceptionLogger logger = ExceptionServices.GetLogger(services); IExceptionHandler handler = ExceptionServices.GetHandler(services); innerResult = (IHttpActionResult) new ExceptionFilterResult(this.ActionContext, exceptionFilters, logger, handler, innerResult); } return innerResult.ExecuteAsync(cancellationToken); }

    由以上的實現代碼可以看出,含有三個類型的過濾器,分別是 IActionFilter、IAuthenticationFilter、IExceptionFilter,該方法在獲取到消息請求後,初始化消息和請求,調用 HttpRequestMessageExtensions.RegisterForDispose(this.Request, (IDisposable) this)該方法進行注冊,該方法會對請求信息進行過濾操作。

    我們接下來看一下Request和RequestContext屬性的具體代碼:

     /// <summary>
    /// 獲取或設置當前ApiController的 HttpRequestMessage。
    /// </summary>
    /// <returns>
    /// 當前ApiController的 HttpRequestMessage。
    /// </returns>
    public HttpRequestMessage Request
    {
      get
      {
        return this.ControllerContext.Request;
      }
      set
      {
        if (value == null)
          throw Error.PropertyNull();
        HttpRequestContext requestContext1 = HttpRequestMessageExtensions.GetRequestContext(value);
        HttpRequestContext requestContext2 = this.RequestContext;
        if (requestContext1 != null && requestContext1 != requestContext2)
          throw new InvalidOperationException(SRResources.RequestContextConflict);
        this.ControllerContext.Request = value;
        HttpRequestMessageExtensions.SetRequestContext(value, requestContext2);
        RequestBackedHttpRequestContext httpRequestContext = requestContext2 as RequestBackedHttpRequestContext;
        if (httpRequestContext == null)
          return;
        httpRequestContext.Request = value;
      }
    }

    /// <summary>
    /// 獲取請求上下文。
    /// </summary>
    /// <returns>
    /// 請求上下文。
    /// </returns>
    public HttpRequestContext RequestContext
    {
      get
      {
        return this.ControllerContext.RequestContext;
      }
      set
      {
        if (value == null)
          throw Error.PropertyNull();
        HttpRequestContext requestContext1 = this.ControllerContext.RequestContext;
        HttpRequestMessage request = this.Request;
        if (request != null)
        {
          HttpRequestContext requestContext2 = HttpRequestMessageExtensions.GetRequestContext(request);
          if (requestContext2 != null && requestContext2 != requestContext1 && requestContext2 != value)
            throw new InvalidOperationException(SRResources.RequestContextConflict);
          HttpRequestMessageExtensions.SetRequestContext(request, value);
        }
        this.ControllerContext.RequestContext = value;
      }
    }

    Request和RequestContext屬性分別用於設置和獲取HttpRequestMessage對象和RequestContext對象,

    ASP.NET Web API除了可以根據HTTP方法來選擇操作方法,還可以根據請求的其他元素選擇操作方法。ASP.NET Web API框架支持從請求元素到操作方法參數的綁定。對於HTTP響應值轉換成適當的HTTP響應消息正文。

四.總結:

   以上是對ASP.NET Web API背景和使用方法,以及對ASP.NET Web API核心對象的簡要介紹,下篇會主要介紹HttpRequestMessage、HttpResponseMessage、HttpClient等三個對象的解析。如果文中有不足和講解錯誤之處,還望大家多多指正。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved