Web API路由


前言

本文描述了 ASP.NET Web API 如何將 HTTP 請求路由到控制器。

如果你熟悉Asp.Net MVC,Web API的路由與Asp.Net MVC的路由是非常類似的。這主要的區別就是Web API使用的是HTTP方法,而不是URI路徑來選擇Action。你也可以在Web API中使用MVC風格的路由。本文不需要有任何Asp.Net MVC的基礎。

Routing Tables路由表

  在Asp.Net Web API中,一個控制器就是一個處理HTTP請求的類,控制器的public 方法被叫做action方法或者簡單的Aciton。當Web API接收到一個請求的時候,它將這個請求路由到一個Action。

  為了確定那個Action被調用,這個框架使用了一個路由表。Visual Studio中Web API的項目模板會創建一個默認路由:

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

這個路由是在WebApiConfig.cs文件中定義的,該文件位於App_Start目錄。

關於WebApiConfig類的更多信息參閱“配置ASP.NET Web API”(暫未實現)

如果你要自己托管(self-host )Web API,你必須直接在HttpSelfHostConfiguration對象上設置路由表。更多信息參閱“自托管Web API"。(暫未實現)

  路由表中的每一個條目都包含一個路由模板。這個Web API默認的路由模版是"api/{controller}/{id}"。在這個模版中,“api”是一個文字式路徑片段,而{controller}和{id}則是占位符變量。

  當Web API框架接收一個HTTP請求時,它會試圖根據路由表中的一個路由模板來匹配其URI。如果無路由匹配,客戶端會接收到一個404(未找到)錯誤。例如,以下URI與這個默認路由的匹配:

  • /api/contacts
  • /api/contacts/1
  • /api/products/gizmo1

然而,以下URI不匹配,因為它缺少“api”片段:

  • /contacts/1

在路由中使用“api”的原因是為了避免與ASP.NET MVC的路由沖突。通過這種方式,可以用“/contacts”進入一個MVC控制器,而“/api/contacts”進入一個Web API控制器。當然,如果你不喜歡這種約定,你也可以修改這個默認路由表。

 一旦一個匹配的路由被發現,Web API便會選擇相應的Controller和Action。

  1.為了找到Controller,Web API會把“控制器”加到{controller}變量的值。

  2.為了找到Action,Web API會查找HTTP方法,然后尋找一個名稱以HTTP方法名開頭的方法。例如,對於一個Get請求,Web API會查找一個以“Get…”開頭的動作,如“GetContact”或“GetAllContacts”等。這種約定只應用於GET、POST、PUT和DELETE方法。通過在你的Controller上使用attributes,你可以啟用其他的HTTP方法。稍后我們就會看到一個例子。

  3.路由模版中其他的占位變量,例如{id},將被映射成Action的參數。

 

讓我們來看一個簡單的例子,假設你定義了以下控制器:

public class ProductsController : ApiController 
{ 
    public void GetAllProducts() { } 
    public IEnumerable<Product> GetProductById(int id) { } 
    public HttpResponseMessage DeleteProduct(int id){ } 
}

以下是一些可能的HTTP請求,以及要被調用的每個動作:

注意,URI中的{id}片段如果出現,會被映射成Action的id參數。在這個例子中,這個控制器定義了兩個GET方法,一個帶有id參數的和一個不帶有id參數的。

另外要注意,POST請求是失敗的,因為該控制器未定義“Post…”方法。

Routing Variations路由變化

 上一節描述了ASP.NET Web API基本的路由機制。本小節描述一些變化。

HTTP方法

替代使用HTTP方法的命名約定,你可以明確的為一個Action指定HTTP方法,通過以HttpGet、HttpPost、HttpPut或者HttpDelete屬性來對Action方法進行修飾。

在下列示例中,FindProduct方法被映射到GET請求:

public class ProductsController : ApiController 
{ 
    [HttpGet] 
    public Product FindProduct(id) {} 
}

允許一個Action對應多個HTTP方法,或者允許除了Get、Put、Post、Delete方法之外的HTTP方法,需要使用AcceptVerbs注解屬性,它以HTTP方法列表作為參數。

復制代碼
public class ProductsController : ApiController
{
    [AcceptVerbs("GET", "HEAD")]
    public Product FindProduct(id) { }

    // WebDAV method
    [AcceptVerbs("MKCOL")]
    public void MakeCollection() { }
}
復制代碼

第一個方法:指示該動作接收HTTP的GET和HEAD方法(這個HEAD沒測試過)

第二個方法:WebDAV方法(基於Web的分布式著作與版本控制的HTTP方法,是一個擴展的HTTP方法

MKCOL是隸屬於WebDAV的一個方法,它在URI指定的位置創建集合(WebDAV更沒見過)

通過Action名稱路由

在默認的路由模版中,這個Web API使用HTTP方法去選擇Action。然而,你也可以在URI中創建包含動作名的路由:

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

在這個路由模板中,{action}參數命名了控制器上的動作方法。采用這種風格的路由,需要使用注解屬性來指明所允許的HTTP方法。例如,假設你的控制器已有如下方法:

public class ProductsController : ApiController 
{ 
    [HttpGet] 
    public string Details(int id); 
}

在這種情況下,一個Get請求"api/Products/Details/1"將會映射到這個這個Details方法。這種風格的路由類似於Asp.Net MVC,而且可能與RPC式的API相接近。(RPC風格不太懂,還沒查資料)

你也可以通過使用ActionName注解屬性來覆蓋動作名。在以下例子中,有兩個動作映射到“api/products/thumbnail/id”。一個支持GET,而另一個支持POST:

復制代碼
public class ProductsController : ApiController 
{ 
    [HttpGet] 
    [ActionName("Thumbnail")] 
    public HttpResponseMessage GetThumbnailImage(int id); 

    [HttpPost] 
    [ActionName("Thumbnail")] 
    public void AddThumbnailImage(int id); 
}
復制代碼

 

Non-Actions

為了防止一個方法被作為一個動作所請求,可以使用NonAction注解屬性。它對框架發出信號:這個方法不是一個動作,,即使它可能與路由規則匹配。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM