本文介绍了ASP.NET Web API路由HTTP请求控制器。

如果你熟悉ASP.NET MVC,Web API路由是和MVC路由非常相似的。主要差别是Web API使用HTTP方法而不是URI路径来选择Action的。你也可以使用MVC的路由配置风格来配置Web API路由,当然本文不是来介绍ASP.NET MVC的。

路由表

在ASP.NET Web API,控制器是一种处理HTTP请求的类。控制器的公共方法被称为动作方法或简单的动作。当Web API框架接收请求时,它将请求发送到一个动作。

要确定调用哪个动作,该框架使用路由表。Visual Studio项目模板为Web API创建了一个默认的路由:

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

这个路由在位于App_Start文件夹中的WebApiConfig.cs文件中定义:

如果想要知道更多相关的配置,你可以访问Configuring ASP.NET Web API.

如果是自主机Web API,你必须设置路由表直接在HttpSelfHostConfiguration对象.想知道更多相关信息,请访问Self-Host a Web API.

路由表中的每一个条目包含一个路由模板。Web API默认的路由模板是"api/{controller}/{id}". 在这个模板中, "api"是固定路径量, {controller} 和 {id} 都是预置位变量.

当Web API框架接收到一个HTTP请求,它将尝试匹配URI对路由表中的路由模板。如果没有匹配到,客户端将收到一个404错误。例如,可以用下列地址来匹配默认的路由规则:

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

但是,下面这个路径将匹配不到,因为它缺少了"api"这个固定路径量:

  • /contacts/1

注: 之所以在路由中使用"api"是为了避免和ASP.NET MVC中的路由冲突。这样,你就可以使用"/contacts"来访问MVC控制器,使用"/api/contacts"来访问API控制器了。当然,如果你不喜欢这么做的话,你可以改变默认路由表。

一旦一条路由被匹配到,Web API将按照以下步骤来选择控制器和Action方法来执行:

  • 定位控制器,Web API把 {controller}变量替换成相应"Controller"的值
  • 定位Action方法,Web API先要获得HTTP方法,然后查找以HTTP方法名开头的Action方法。比如有一个GET请求,Web API首先去寻找以"Get..."开头的Actin方法,比如"GetContact"或者"GetAllContacts"。但这仅仅适用于GET, POST, PUT和DELETE这几个方法。如果你想要在你的控制器使用其他的HTTP方法,你就得使用属性了,我们将会在后面的例子中看到.
  • 路由模板中的其他占位符变量,比如 {id},将会映射到Action参数中。

让我们来看一个例子。假设定义有如下控制器:

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 GetAllProducts (none)
GET api/products/4 GetProductById 4
DELETE api/products/4 DeleteProduct 4
POST api/products (no match)  

请注意URI中的{id}这个字段,如果有这个变量,它会映射到包含有id变量的Action方法。在这个例子中,控制器定义了两个GET方法,一个有id这个变量,一个没有。并且,POST请求将会失败,因为控制器没有定义"Post..."方法。

路由变化

上一节介绍了ASP.NET Web API的基本路由机制。下面来讲一下路由变化。

HTTP方法

与其使用命名约定为HTTP方法,你可以显式地用HttpGetHttpPutHttpPost,或HttpDelete属性来指定HTTP方法。

在下面的例子中,FindProduct这个方法将会处理GET请求:

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

为了使一个Action支持多种HTTP方法,或者说允许HTTP方法更多的支持GET, PUT, POST和DELETE, 你需要用到AcceptVerbs这个属性,它允许配置一个HTTP方法列表。

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

根据Action名字来路由

有了默认的路由配置模板,Web API使用HTTP方法来选择Action。不过你仍然可以创建一个路由并且用Action方法名字来显示在URI中:

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

在这条路由模板中,控制器使用{action}这个变量名来定义Action方法。按照这种方式来定义的路由,我们需要使用属性来指定可以接受的HTTP方法。例如,你的控制器中包含如下的方法:

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

在这个例子中,一个GET请求”api/products/details/1”将会映射到详细方法。这种风格的路由类似于ASP.NET MVC,并可适当的RPC风格的API。

你可以使用ActionName属性来重新定义Action方法名。在下面的例子中,包含两个Acton方法,他们都映射到"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

为了防止某个方法被误认做一个Action, 我们可以使用NonAction这个属性。标注为NonAction的方法即表示该方法不是一个可执行的Action,即使它被路由规则给匹配到。

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

延伸阅读

本文只是简单的介绍了一下,如果想要了解更多关于更精确的框架如何用路由来匹配URI并选择控制器和Action来执行的详细内容,可以访问Routing and Action Selection

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

注:首次翻译,肯定有很多地方有错误,请大家批评指教。

WebApi初探之路由配置的更多相关文章

  1. ASP.NET Core MVC/WebAPi如何构建路由?

    前言 本节我们来讲讲ASP.NET Core中的路由,在讲路由之前我们首先回顾下之前所讲在ASP.NET Core中的模型绑定这其中有一个问题是我在项目当中遇见的,我们下面首先来看看这个问题. 回顾A ...

  2. ASP.NET Web API 2系列(二):灵活多样的路由配置

    1. 导言 路由系统是请求消息进入ASP.NET Web API消息处理管道的第一道屏障,其根本目的在于利用注册的路由对请求的URL进行解析以确定目标HTTPController和Action的名称, ...

  3. .NetCore MVC中的路由(1)路由配置基础

    .NetCore MVC中的路由(1)路由配置基础 0x00 路由在MVC中起到的作用 前段时间一直忙于别的事情,终于搞定了继续学习.NetCore.这次学习的主题是MVC中的路由.路由是所有MVC框 ...

  4. ASP.NET WebForms MapPageRoute 路由配置

    MapPageRoute 应该是 ASP.NET 4.0 中的东西,但现在我是第一次使用它,使用场景是:MVC 混合使用 WebForm,然后对 WebForm 进行路由配置,当然也可以使用 ISAP ...

  5. MVC路由配置

    目录 URL Routing 的定义方式 示例准备 给片段变量定义默认值 定义静态片段 自定义片段变量 自定义片段变量的定义和取值 将自定义片段变量作为Action方法的参数 指定自定义片段变量为可选 ...

  6. ui-router带参数的路由配置

    ui-router带参数的路由配置 使用ng-route的时候带参数的连接这样配置: $routeProvider.when('item/itemid/:itemid', { templateUrl: ...

  7. [水煮 ASP.NET Web API2 方法论](3-8)怎样给指定路由配置处理器

    阅读导航 问题 解决方案 工作原理 代码演示 问题 如果仅仅针对指定的路由进行某些特定的消息处理,而不是应用于所有路由,我们应该怎么做呢? 解决方案 ASP.NET WEB API 的很多功能都内建了 ...

  8. Linux和Windows路由配置

    Linux和Windows路由配置 一.配置路由 1-       原则上一台主机只能有一条缺省路由.如果一台主机上有多个网段的话,请配置能够上网的那个网段的网关为缺省路由 Linux配置缺省路由: ...

  9. WebForm MapPageRoute 路由配置(转载)

    使用场景是:MVC 混合使用 WebForm,然后对 WebForm 进行路由配置 http://www.cnblogs.com/xishuai/archive/2015/02/26/web-form ...

随机推荐

  1. JavaSE 第二次学习随笔(String的坑 + ==)

    String 类是一个final类, 其内部是使用的 private final char value[]; 来存储内容, 其既可以当作一个基本类型来使用也可以当作一个类来使用;final 类(Str ...

  2. PAT (Basic Level) Practice 1040 有几个PAT

    个人练习 字符串 APPAPT 中包含了两个单词 PAT,其中第一个 PAT 是第 2 位(P),第 4 位(A),第 6 位(T):第二个 PAT 是第 3 位(P),第 4 位(A),第 6 位( ...

  3. ESP-01S-ESP8266入门教程

    1.模块实物 2.引脚说明 3.连接说明,按下图将引脚连接到PC的串口(VCC接3V,GND接地,TX接串口TX,RX接串口的RX,CH_PD接3V,否则wifi不工作) 4.通过该PC串口配置WiF ...

  4. perl连接mysql数据库

    首先需要安装 ppm install DBD::mysql use strict; use DBI; my $host = "localhost"; # 主机地址 my $driv ...

  5. hover 改变另一个标签的属性

  6. Android stadio 关联源码

    有时候,你想在Android stadio 里看源码, 然后Android stadio 会提示你去下载. 但是下载完了之后,有时候stadio 还是不能看源码.后来,参考这位博客,搞完了. http ...

  7. Maven学习 (三) 使用m2eclipse创建web项目

    1.首先确认你的eclipse已经安装好m2eclipse的环境,可以参照上两篇Maven学习内容 2.新建一个maven的项目 3.下一步默认配置,使用默认的工作空间,或者你可以自己选择其他的空间 ...

  8. Djano之写api使用django_rest_framework【海瑞博客】

    使用django rest framework 可以更快速和友好的编写api,当然网上有很多教程,对于高手来说相对很简单,对于新手来说,根本搞不明白.那是你没有搞明白你自己的职责,做为后端,我们只要提 ...

  9. 孤荷凌寒自学python第四十七天通用跨数据库同一数据库中复制数据表函数

    孤荷凌寒自学python第四十七天通用跨数据库同一数据库中复制数据表函数 (完整学习过程屏幕记录视频地址在文末) 今天继续建构自感觉用起来顺手些的自定义模块和类的代码. 今天打算完成的是通用的(至少目 ...

  10. [转载]kd tree

    [本文转自]http://www.cnblogs.com/eyeszjwang/articles/2429382.html k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据 ...