zoukankan      html  css  js  c++  java
  • Web API-路由(一)

    这一篇文章描述了ASP.NET API如何将HTTP请求路由到控制器。

    如果你熟悉ASP.NET MVC,Web API路由和MVC路由非常相似,主要的不同地方是Web API使用HTTP方法,而不是URI路径去选择action。你也能够在WebAPI中使用MVC风格的路由,这一篇文章不讨论任何有关MVC的知识。

    路由表:

    在ASP.NET Web API 中,一个控制器是一个处理HTTP请求的类,Controller中的公共方法称作action方法或者简单方法,当Web API框架接收到一个请求,框架将请求路由到一个action。

    Web API框架使用路由表(route table)来决定哪一个action被调用。VS的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 .

    如果使用自寄宿(self-host)的Web API,必须通过HttpSelfHostConfiguration自己设置路由表,更多信息可以参考:Self-Host a Web API.

    路由表中的每个条目包含一个模板,默认的Web API路由模版是“api/{controller}/{id}”。这个模版里,“api”是一个纯文本路径段,{controller}和{id}是占位符(参数变量)。当Web API框架接收到一个请求时,尝试将URI与路由表中的项(路由模版)匹配,如果没有可以匹配的路由项,则返回一个404错误,比如下面三个uri可以和默认的路由模版进行匹配。

    /api/contacts

    /api/contacts/1

    /api/products/gizmo1

    但是/contacts/1这个就匹配不了因为缺少“api"段。

    :Web API 路由模版使用“api”开头是为了避免与MVC的路由模版冲突,这样你能够使用"/contacts"URI去路由到一个MVC controller,而使用"api/contacts" 路由到一个Web API controller。当然,如果你不喜欢,可以修改默认的路由模版。


    一旦找到匹配的路由,Web API则进行controller和action的选择

    --To find the controller, Web API adds "Controller" to the value of the {controller} variable.

    --匹配action,Web API 查看本次HTTP 方法,比如:如果是GET方法,则在controller中查找Get开头的方法,这种查询以HTTP请求方式开头的action的方式只适合GET , POST , PUT 和 DELETE 方式Http请求???,你可以通过为action添加标识属性的方法来指定action可匹配的HTTP请求方式以及允许其他的HTTP请求方式。

    --其他的路由模版中的占位符变量,比如{id},映射为一个action参数。

    下面看一个例子:定义一个如下的controller

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

    下面表格展示了不同的URI所调用的action

    HTTP Method

    URI Path

    Action

    参数

    GET

    api/products

    GetAllProducts

    GET

    api/products/4

    GetProductById

    4

    DELETE

    api/products/4

    DeleteProduct

    4

    POST

    api/products

    没有匹配的action

     

    注意:这里的{id}段,如果指定了{id}的值,则调用有id参数的action方法 GetProductById。

    因为没有定义Post开头的aciton方法,所以POST方式的请求找不到匹配的action。


    路由拓展

    --使用Http Methods 标识属性:除了定义以HTTP请求方式开头的action方法外,我们可以使用HttpGet  , HttpPut  ,  HttpPost  或者 HttpDelete标识属性来指定一个action方法匹配的HTTP请求方式(与使用HTTP请求方式开头的方法名效果一样),例如,下面这个方法可以和GET请求方式的HTTP请求匹配。

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

    如果一个action方法需要匹配多种HTTP请求方式,或者需要匹配除GET,POST,PUT,DELETE请求方式外的其他请求,可以使用AccptVerbs标识属性。例如:FindProduct方法可以同时匹配 GET 和 HEAD请求。

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

    --使用MVC风格的路由

    定义路由模版:

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

    在这个路由模版中,{action}参数指定controller中的action的名称,使用这种风格的路由,需要使用标识属性指定action允许匹配的HTTP请求方式,比如:必须使用[HttpGet]、[HttpPost]等标识属性。

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

    上面的例子中一个“api/products/details/1”的GET请求,将映射到Details方法。这种风格很像MVC,可能更适合用在一个RPC-style API中。

    --使用ActionName属性定义action的别名:

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

    我们可以发送uri为 "api/products/thumbnail/id"的GET请求 map to GetThumbnailImage方法。

    发送uri为"api/products/thumbnail/id"的POST请求 map to AddThumbnailImage 方法。

    通过上面几个例子可以看出,可以使用标识属性,配置一个action方法用作匹配路由的名称和方法。

    --使用[NonAction]标识属性来指定一个方法不为action方法

  • 相关阅读:
    LeetCode--Reorder List
    LeetCode--Combination Sum
    LeetCode--Binary Tree Level Order Traversal
    LeetCode--Plus One
    第五届蓝桥杯决赛CC++B组——生物芯片
    第五届蓝桥杯决赛CC++B组——Log大侠
    第五届蓝桥杯决赛CC++B组——出栈次序
    1098 均分纸牌 ——http://codevs.cn/problem/1098/
    1294 全排列——http://codevs.cn/problem/1294/
    1501 二叉树最大宽度和高度——http://codevs.cn/problem/1501/
  • 原文地址:https://www.cnblogs.com/zkun/p/4169650.html
Copyright © 2011-2022 走看看