zoukankan      html  css  js  c++  java
  • 【转载】ASP.NET MVC Web API 的路由选择

    此文章描述了ASP.NET Web API如何将Http请求路由到controller。

    路由表

    在ASP.NET Web API中,controller是用来处理HTTP请求的一个类。这个类中用于处理HTTP请求的的公共方法被称之为action method或者简称action。当Web API框架接收到一个请求时,会将这个请求路由到一个action来处理。

    ASP.NET Web API框架通过使用路由表来确定哪个action方法被调用。Visual Studio 中的ASP.NET Web API项目模板会创建一个默认的路由:

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

    这个默认路由被定义在App_Start目录下的WebApiConfig.cs文件中。

    关于WebApiConfig类的更多信息,参见Configuring ASP.NET Web API.

    路由表中的每一条记录都包含了一个路由模板。默认的Web API路由模板是"api/{controller}/{id}"。在这个模板中,"api"是固定的值,而{controller}和{id}则仅仅是占位符而已(类似于string.Format方法中的格式化字符串使用{0}占位)。

    当Web API框架接收到一个HTTP请求时,它会尝试使用路由表中的路由模板来匹配请求的URI。如果没有匹配的模板,客户端就会接收到一个404错误。如下的几个URI是匹配默认模板的:

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

    但是下面的这个URI是不匹配的,因为它缺少"api"部分

    /contacts/1

    注意:之所以在路由模板中使用"api"这个固定量是为了避免与ASP.NET MVC路由冲突。在ASP.NET MVC中,你可以使用"/contacts"来匹配一个普通的controller,而使用"/api/contacts"来匹配Web API的controller。当然,如果你不喜欢这种约定,也可以更改默认的路由表。

    一旦发现了匹配的路由模板,Web API就会选择合适的controller和action:

    1.选择controller,Web API会在匹配{controller}占位符的值后面加上"Controller",来查找同名的controller

    2.选择action,Web API会查找以HTTP请求的method开头的方法。比如,有一个Get请求,那么Web API就会查找controller中以Get开头的方法,比如"GetContact"或者"GetAllContacts".这种约定仅适用于GET,POST,PUT和DELETE方法,你可以通过在方法上面添加特性来启用某种HTTP method,我们会在后面展示这个例子。

    3.路由模板里的其它占位符,比如{id},会被映射到action的参数列表。

    我们先来看一个例子,假设有如下定义的一个controller

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

    下面是一些可能的HTTP请求和会被调用到的action

    HTTP Method URI Path Action Parameter
    GET api/products GetAllPriducts none
    GET api/products/4 GetPriductById 4
    DELETE api/products/4 DeleteProduct 4
    POST api/products no match  

    注意URI中的{id}部分,如果出现的话,这部分的值将会被映射为action方法的名为id的参数。在这个例子里,controller定义了两个Get开头的方法,其中有一个有一个名为id的参数,另外一个无参数。

    Route Variations(不知道怎么翻译,路由变体?)

    除了使用命名约定以外,还可通过为action添加HttpGet,HttpPut,HttpPost或者HttpDelete特定来显示指定该action响应的Http method。

    下面的例子中,FindProduct方法会对应到Http的Get请求:

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

    为了使一个action可以响应多种HTTP method,或者响应除了GET,PUT,POST,DELETE四种之外的其它HTTP method,可以为action指定AcceptVerbs特性,这个特性可以接受一个Http Method列表。

    public class ProductsController : ApiController
    {
        [AcceptVerbs("GET", "HEAD")]
        public Product FindProduct(id) { }
    
        // WebDAV method
        [AcceptVerbs("MKCOL")]
        public void MakeCollection() { }
    }

    通过名字进行路由(Routing by Action Name)

    默认路由模板使用Http method来选择action,但是你也可以使用action的名字来进行路由。

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

    在这个模板中,{action}占位符是controller中action的名字,这种形式的路由模板,通过附加在action之上的特性来确定该action响应哪种Http method,例如,假设controller中有如下的方法

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

    在这个例子中,一个请求“api/products/details/1”的http get请求会被映射到Details方法,这种路由风格类似于ASP.NET MVC的路由风格,而且更适用于RPC-style API(远程过程调用风格的api?)

    通过使用ActionName属性,我们可以指定特定的action名字,而不使用action的方法名,在下面的例子中,有两个action都会响应"api/products/thumbnail/id"这个uri,但是分别对应get method和post method:

    public class ProductsController : ApiController
    {
        [HttpGet]
        [ActionName("Thumbnail")]
        public HttpResponseMessage GetThumbnailImage(int id);
    
        [HttpPost]
        [ActionName("Thumbnail")]
        public void AddThumbnailImage(int id);
    }

    非action方法

    对于controller中的方法,我们并不希望都会响应HTTP Method,也就是说controller中可以包含非action的方法,那么这时要给这些方法添加NonAction特性,这样Web Api框架在进行路由匹配的时候就会忽略这些方法。

    // Not an action method.
    [NonAction]  
    public string GetPrivateData() { ... }

    英文原文:http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

    转自:http://www.cnblogs.com/onepiece_wang/archive/2013/03/14/2960535.html

  • 相关阅读:
    实时信号阻塞队列大小测试
    实时信号和非实时信号
    [Linux]关于sigprocmask函数的讨论
    java中Map集合的常用方法 (转)
    佛跳墙
    百万数据查询效率提高方法(转)
    bootstrap table 前后端分页(超级简单)
    bootstrap table 分页序号递增问题 (转)
    Spring boot+mybatis+thymeleaf 实现登录注册,增删改查
    js弹出对话框的三种方式(转)
  • 原文地址:https://www.cnblogs.com/hycms/p/3940389.html
Copyright © 2011-2022 走看看