此文章描述了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

【转载】ASP.NET MVC Web API 的路由选择的更多相关文章

  1. 【转载】ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查.目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的.下面我们通过创建一个简单的Web API来管理联系 ...

  2. ABP 教程文档 1-1 手把手引进门之 AngularJs, ASP.NET MVC, Web API 和 EntityFramework(官方教程翻译版 版本3.2.5)含学习资料

    本文是ABP官方文档翻译版,翻译基于 3.2.5 版本 转载请注明出处:http://www.cnblogs.com/yabu007/  谢谢 官方文档分四部分 一. 教程文档 二.ABP 框架 三. ...

  3. ASP.NET MVC Web API Post FromBody(Web API 如何正确 Post)

    问题场景: ASP.NET MVC Web API 定义 Post 方法,HttpClient 使用 JsonConvert.SerializeObject 传参进行调用,比如 Web Api 中定义 ...

  4. ASP.NET MVC Web API For APP

    近来很多大型的平台都公开了Web API.比如百度地图 Web API,做过地图相关的人都熟悉.公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过在浏览器中使用 JavaScr ...

  5. [译]ABP框架使用AngularJs,ASP.NET MVC,Web API和EntityFramework构建N层架构的SPA应用程序

    本文转自:http://www.skcode.cn/archives/281 本文演示ABP框架如何使用AngularJs,ASP.NET MVC,Web API 和EntityFramework构建 ...

  6. Asp.net mvc web api 在项目中的实际应用

    Asp.net mvc web api 在项目中的实际应用 前言:以下只是记录本人在项目中的应用,而web api在数据传输方面有多种实现方式,具体可根据实际情况而定! 1:数据传输前的加密,以下用到 ...

  7. ASP.NET MVC Web API 学习笔记---第一个Web API程序

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...

  8. 实战 ASP.NET MVC Web API

    实战 ASP.NET MVC Web API Web API 框架基于 ASP.NET MVC 框架开发,是一个面向 Http 协议的通信框架.相对于 WCF 而言,Web API 只面向于 Http ...

  9. ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查. 目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的. 下面我们通过创建一个简单的Web API来管理 ...

随机推荐

  1. WPF,Silverlight与XAML读书笔记第四十五 - 外观效果之模板

    说明:本系列基本上是<WPF揭秘>的读书笔记.在结构安排与文章内容上参照<WPF揭秘>的编排,对内容进行了总结并加入一些个人理解. 模板允许用任何东西完全替换一个元素的可视树, ...

  2. java中基本类型和包装类型实践经验

    至今,小菜用java快两年了,有些事,也该有个总结. 基本类型和包装类型的概念在本文不作赘述. 如果这两种类型直接使用,倒没什么值得讨论的,无非就是自动装箱拆箱,java可以让你感觉不到他们的存在,但 ...

  3. 一句话解释c#中的特性,你了解多少

    自己闲着无聊写的,当然有些描述不是十分准确,毕竟一句话不能表达太多意思. 委托:把方法当做参数进行传递. 泛型:在类.方法中对使用的类型参数化. 匿名方法:委托及调用委托的简化版. Lambda表达式 ...

  4. easy-ui JOB 及 小记录

    $:获取  $.ajax({             type: "POST" ,             url: "" ,             cont ...

  5. MyBatis学习总结(二)——使用MyBatis对表执行CRUD操作

    一.使用MyBatis对表执行CRUD操作--基于XML的实现 1.定义sql映射xml文件 userMapper.xml文件的内容如下: 1 <?xml version="1.0&q ...

  6. Codeforces Round #380 (Div. 2) 总结分享

    B. Spotlights 题意 有n×m个格子的矩形舞台,每个格子里面可以安排一个演员或聚光灯,聚光灯仅可照射一个方向(俯视,上下左右).若聚光灯能照到演员,则称为"good positi ...

  7. Oracle日期函数和循环总结

    一,日期相关的函数 Select to_char(sysdate,'Q') from dual;--指定日期的季度 Select to_char(sysdate,'MM') from dual;--月 ...

  8. @@IDENTITY与SCOPE_IDENTITY()

    在一条 INSERT.SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含语句生成的最后一个标识值.如果语句未影响任何包含标识列的表,则 @@IDENTITY 返回 NULL. ...

  9. CSS选择器的浏览器支持

    CSS1 CSS2 CSS 3 :hover 在IE6中只有a元素可用. E:empty 貌似在webkit核心浏览器中有些小bug. 如果这个bug依然存在,不太确定如何测试. IE6不支持.cla ...

  10. 【转】C#中如何实现左截取和右截取字符串

    使用C#语法编写程序时,我们需要截取一个字符串左边或右边的若干个字符,该如何操作呢?在VB中可以使用left或right函数实现,C#中没有提供这样的函数呢?答案是没有.但是,C#中提供Substri ...