Web API路由

2020-12-13 13:44

阅读:594

标签:blog   http   io   os   ar   使用   sp   strong   文件   

前言

本文描述了 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目录。

soscw.com,搜素材

关于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 GetProductById(int id) { } 
    public HttpResponseMessage DeleteProduct(int id){ } 
}

以下是一些可能的HTTP请求,以及要被调用的每个动作:

soscw.com,搜素材

注意,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方法列表作为参数。

soscw.com,搜素材
public class ProductsController : ApiController
{
    [AcceptVerbs("GET", "HEAD")]
    public Product FindProduct(id) { }

    // WebDAV method
    [AcceptVerbs("MKCOL")]
    public void MakeCollection() { }
}
soscw.com,搜素材

第一个方法:指示该动作接收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:

soscw.com,搜素材
public class ProductsController : ApiController 
{ 
    [HttpGet] 
    [ActionName("Thumbnail")] 
    public HttpResponseMessage GetThumbnailImage(int id); 

    [HttpPost] 
    [ActionName("Thumbnail")] 
    public void AddThumbnailImage(int id); 
}
soscw.com,搜素材

 

Non-Actions

为了防止一个方法被作为一个动作所请求,可以使用NonAction注解属性。它对框架发出信号:这个方法不是一个动作,,即使它可能与路由规则匹配。

Web API路由

标签:blog   http   io   os   ar   使用   sp   strong   文件   

原文地址:http://www.cnblogs.com/soundcode/p/4054001.html


评论


亲,登录后才可以留言!