web api Route属性定义
ASP.NET Web API路由,简单来说,就是把客户端请求映射到对应的Action上的过程。在"ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置"一文中,体验了通过模版、惯例、HTTP方法来设置路由,这种做法的好处是把路由模版统一放在了App_Start文件夹下的WebApiConfig类中,方便管理,但缺点是不够灵活。 REST把一切都看成资源,有时候,一个资源连带子资源,比如Customer和Orders密切关联,我们可能希望输入这样的请求:customers//orders,但仅仅凭借惯例,很难实现这种路由。而实际上,ASP.NET Web API为我们准备了Route特性,该特性可以直接打到Action上,使用非常灵活、直观。 下面就在ASP.NET MVC4下来体验Route特性的使用方法。 允许Route特性 首先需要在WebApiConfig中设置。 using System.Web.Http;
namespace MyRoutingAttributes4
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//设置特性路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// 取消注释下面的代码行可对具有 IQueryable 或 IQueryable<T> 返回类型的操作启用查询支持。
// 若要避免处理意外查询或恶意查询,请使用 QueryableAttribute 上的验证设置来验证传入查询。
// 有关详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=279712。
//config.EnableQuerySupport();
// 若要在应用程序中禁用跟踪,请注释掉或删除以下代码行
// 有关详细信息,请参阅: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
}
}
} 以上的MapHttpAttributeRoutes方法只在ASP.NET Web API较新的版本中才有,如果你的版本比较低,可以通过"NuGet程序包管理器控制台"卸载旧版本,安装最新版本。 Uninstall-Package microsoft.aspnet.webapi –Force
install-package microsoft.aspnet.webapi 接下来,在Global.asax中,需要把原先注册WebApiConfig的方式注释掉,采纳新的方式,如下: public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
//WebApiConfig.Register(GlobalConfiguration.Configuration);
//Web API,启动特性路由
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
} 这时候运行项目可能会报如下错误: 这是因为在下载使用ASP.NET Web API最新版本的时候,顺带下载了一个最新版本的icrosoft.AspNet.WebApi.HelpPage。可以把最新版的HelpPage卸载掉,再下载相对老的版本。 Uninstall-Package Microsoft.AspNet.WebApi.HelpPage –Force
Install-Package Microsoft.AspNet.WebApi.HelpPage -Pre 使用Route特性 创建一个Cusomter类。 namespace MyRoutingAttributes4.Models
{
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
} 创建一个Order类。 namespace MyRoutingAttributes4.Models
{
public class Order
{
public int Id { get; set; }
public decimal Total { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; }
}
} 创建一个Database类,用来获取Order集合。 using System.Collections.Generic;
using System.Linq;
using MyRoutingAttributes4.Models;
namespace MyRoutingAttributes4
{
public class Database
{
public static IEnumerable<Order> GetOrdersByCustomerId(int customerId)
{
return GetOrders().Where(o => o.CustomerId == customerId);
}
private static IEnumerable<Order> GetOrders()
{
Customer cus1 = new Customer() { Id = , Name = "张三" };
Customer cus2 = new Customer() { Id = , Name = "李四" };
List<Order> orders = new List<Order>()
{
new Order(){Id = , Total = 80M, CustomerId = , Customer = cus1},
new Order(){Id = , Total = 100M, CustomerId = , Customer = cus1},
new Order(){Id = , Total = 120M, CustomerId = , Customer = cus2}
};
return orders;
}
}
} 创建一个空的API控制器,编写如下: using System.Collections.Generic;
using System.Web.Http;
using MyRoutingAttributes4.Models;
namespace MyRoutingAttributes4.Controllers
{
public class OrdersController : ApiController
{
[Route("customers/{customerId}/orders")]
[HttpGet]
public IEnumerable<Order> FindOrdersByCustomer(int customerId)
{
return Database.GetOrdersByCustomerId(customerId);
}
}
} 在浏览器中输入如下: 如果你使用的是ASP.NET MVC4进行开发,在程序第一次运行的时候,可能会报如下错误: [A]System.Web.WebPages.Razor.Configuration.HostSection 无法强制转换为 [B]System.Web.WebPages.Razor.Configuration.HostSection。类型 A 源自“System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”(在上下文“Default”中的“C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Web.WebPages.Razor/v4.0_2.0.0.0__31bf3856ad364e35/System.Web.WebPages.Razor.dll”位置处)。类型 B 源自“System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”(在上下文“Default”中的“C:/Windows/Microsoft.NET/Framework/v4.0.30319/Temporary ASP.NET Files/vs/feb7ce97/a525d58a/asse 这是因为,在下载最新版本的ASP.NET Web API的时候,用到了Razor的最新版本。需要在根目录下的Web.config中作如下配置: <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
......
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="2.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime> 使用RoutePrefix特性 如果想给某个API控制器中的所有Action加上一个前缀,可把RoutePrefix特性打在API控制器上。 比如我们希望是这样的格式:http://localhost/api/customers/1/orders 这样来修改OrdersController。 using System.Collections.Generic;
using System.Web.Http;
using MyRoutingAttributes4.Models;
namespace MyRoutingAttributes4.Controllers
{
[RoutePrefix("api")]
public class OrdersController : ApiController
{
[Route("customers/{customerId}/orders")]
[HttpGet]
public IEnumerable<Order> FindOrdersByCustomer(int customerId)
{
return Database.GetOrdersByCustomerId(customerId);
}
}
} 还可以在Route特性中使用~来重写Action的前缀规则。 using System.Collections.Generic;
using System.Web.Http;
using MyRoutingAttributes4.Models;
namespace MyRoutingAttributes4.Controllers
{
[RoutePrefix("api")]
public class OrdersController : ApiController
{
[Route("~/myapi/customers/{customerId:int}/orders")]
[HttpGet]
public IEnumerable<Order> FindOrdersByCustomer(int customerId)
{
return Database.GetOrdersByCustomerId(customerId);
}
}
} RoutePrefix特性定义的前缀还可以带参数变量: [RoutePrefix("api/{customerId}")]
public class OrdersController : ApiController 路由约束 可以通过"{参数变量名称:约束}"来约束路由中的参数变量。 [Route("users/{id:int}"]
public User GetUserById(int id) { ... }
[Route("users/{name}"]
public User GetUserByName(string name) { ... }
以上,如果片段变量id为int类型,就路由到第一个Action,如果不是,路由到第二个Action。 ASP.NET Web API内置约束包括: {x:alpha} 约束大小写英文字母
{x:bool}
{x:datetime}
{x:decimal}
{x:double}
{x:float}
{x:guid}
{x:int}
{x:length()}
{x:length(,)} 约束长度范围
{x:long}
{x:maxlength()}
{x:min()}
{x:range(,)}
{x:regex(正则表达式)} 可以为一个参数变量同时设置多个约束:
[Route("api/{id:int:min(1)}")] 实现IHttpRouteConstraint接口,可自定义约束规则。实现一个不能为0的约束。 public class NonZeroConstraint : IHttpRouteConstraint
{
public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName,
IDictionary<string, object> values, HttpRouteDirection routeDirection)
{
object value;
if (values.TryGetValue(parameterName, out value) && value != null)
{
long longValue;
if (value is long)
{
longValue = (long)value;
return longValue != ;
}
string valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
if (Int64.TryParse(valueString, NumberStyles.Integer,
CultureInfo.InvariantCulture, out longValue))
{
return longValue != ;
}
}
return false;
}
} 在App_Start文件夹中的WebApiConfig中注册自定义约束。 public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var constraintResolver = new DefaultInlineConstraintResolver();
constraintResolver.ConstraintMap.Add("nonzero", typeof(NonZeroConstraint));
config.MapHttpAttributeRoutes(constraintResolver);
}
} 使用自定义约束。 [Route("{id:nonzero}")] 可选参数及其默认值 如果一个路由参数变量是可选的,同时必须给该参数一个默认值。 [Route("api/{id:int?}")]
public IEnumerable<T> Get(int id = ){}
在约束后面加?,表示可选,在方法参数中给id设置默认值。 给路由设置名称 public class BooksController : ApiController
{
[Route("api/books/{id}", Name="GetBookById")]
public BookDto GetBook(int id)
{
// Implementation not shown...
}
[Route("api/books")]
public HttpResponseMessage Post(Book book)
{
// Validate and add book to database (not shown)
var response = Request.CreateResponse(HttpStatusCode.Created);
// Generate a link to the new book and set the Location header in the response.
string uri = Url.Link("GetBookById", new { id = book.BookId });
response.Headers.Location = new Uri(uri);
return response;
}
} 路由优先顺序 Route特性设置的路由优先顺序是根据惯例和RouteOrder属性来确定的。 惯例是: 、静态片段变量
、带约束的片段变量
、不带约束的片段变量
、带约束的通配符片段变量
、不带约束的通配符片段变量 RouteOrder属性的默认值是0,属性值越小,排在越前面。 [RoutePrefix("orders")]
public class OrdersController : ApiController
{
[Route("{id:int}")] // constrained parameter
public HttpResponseMessage Get(int id) { ... }
[Route("details")] // literal
public HttpResponseMessage GetDetails() { ... }
[Route("pending", RouteOrder = )]
public HttpResponseMessage GetPending() { ... }
[Route("{customerName}")] // unconstrained parameter
public HttpResponseMessage GetByCustomer(string customerName) { ... }
[Route("{*date:datetime}")] // wildcard
public HttpResponseMessage Get(DateTime date) { ... }
}
以上,路由的优先顺序是: orders/details 静态片段变量,RouteOrder属性值为0
orders/{id} 带约束的片段变量,RouteOrder属性值为0
orders/{customerName} 不带约束的片段变量,RouteOrder属性值为0
orders/{*date} 带约束的通配符片段变量,RouteOrder属性值为0
orders/pending RouteOrder属性值为1 装载 仅供保存学习
web api Route属性定义的更多相关文章
- Net Web Api Route
Asp.Net Web Api Route 在目前的主流架构中,我们越来越多的看到web Api的存在,小巧,灵活,基于Http协议,使它在越来越多的微服务项目或者移动项目充当很好的service ...
- 打造属于自己的支持版本迭代的Asp.Net Web Api Route
在目前的主流架构中,我们越来越多的看到web Api的存在,小巧,灵活,基于Http协议,使它在越来越多的微服务项目或者移动项目充当很好的service endpoint. 问题 以Asp.Net W ...
- Web Api Route 注册要放在 Mvc Route 注册前
今天想研究一下Web Api,写了一个测试Api,打开网站后浏览一下,可是却提示找不到方法,刚开始以为哪里配置错了,可找了半天也没见. 因为我是在一个现有Mvc站点做的Demo,所以打算新建一个Mvc ...
- Web API使用记录系列(一)创建API项目与基本配置
本系列文章主要记录Web API使用过程中的一些个人总结,包括创建API项目.基础配置.ApiTestClient使用与HelpPage页面的优化.Owin与OAuth的使用等. 本节主要内容是API ...
- Asp.Net Web API 2第八课——Web API 2中的属性路由
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 路由就是Web API如何 ...
- Web API 2中的属性路由
Web API 2中的属性路由 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.ht ...
- Web APi 2.0优点和特点?在Web APi中如何启动Session状态?
前言 曾几何时,微软基于Web服务技术给出最流行的基于XML且以扩展名为.asmx结尾的Web Service,此服务在.NET Framework中风靡一时同时也被.NET业界同仁所青睐,几年后在此 ...
- ASP.NET Web API 应用教程(一) ——数据流使用
相信已经有很多文章来介绍ASP.Net Web API 技术,本系列文章主要介绍如何使用数据流,HTTPS,以及可扩展的Web API 方面的技术,系列文章主要有三篇内容. 主要内容如下: I 数据 ...
- 【ASP.NET MVC 5】第27章 Web API与单页应用程序
注:<精通ASP.NET MVC 3框架>受到了出版社和广大读者的充分肯定,这让本人深感欣慰.目前该书的第4版不日即将出版,现在又已开始第5版的翻译,这里先贴出该书的最后一章译稿,仅供大家 ...
随机推荐
- 基于ACE的c++线程封装
1. 基本需求 1) 一个基类,其某个方法代表一个线程的生命运行周期.之后通过继承自这个基类来实现个性化线程类: 2) 具备类似QObject的定时器设置功能: 3) 提供在线程对象中同步和异步执行方 ...
- AngularJS 路由
AngularJS 路由允许我们通过不同的 URL 访问不同的内容. 通过 AngularJS 可以实现多视图的单页Web应用(single page web application,SPA). 通常 ...
- Excel文件下载功能
HtmlTextWriter:能够帮助我们快速生成html语句. 下载功能实现代码 protected void Button1_Click(object sender, EventArgs e) { ...
- ArrayList常用操作
List使用: package com.collection.list; import java.util.ArrayList; import java.util.Arrays; import jav ...
- Codeforces Round #382 Div. 2【数论】
C. Tennis Championship(递推,斐波那契) 题意:n个人比赛,淘汰制,要求进行比赛双方的胜场数之差小于等于1.问冠军最多能打多少场比赛.题解:因为n太大,感觉是个构造.写写小数据, ...
- Add Indexer to DynamicJson
/*-------------------------------------------------------------------------- * DynamicJson * ver 1.2 ...
- shell获取文件最后100行,开头100行,指定开始行和结束行的内容
文件最后100行:tail -n100 filePath: 文件开头100行:head -n100 filePath: 文件指定开始行和结束行的内容:sed '1,100p' filePath: 文件 ...
- jQuery实战
1.获取标签在文档中的位置 var left = $('.selected').offset().left; var top = $('.selected').offset().top; 2.获取选中 ...
- 使用IntelliJ IDEA 配置Maven(入门)【转】
1.在IntelliJ IDEA中配置maven 打开-File-Settings 2.新建maven WEB项目 打开-File-New-Project 点击NEXT 点击NEXT 添加的配置 ...
- 任务栏显示进度条 CreateComObject(CLSID_TaskbarList) as ITaskbarList4
http://www.cnblogs.com/jxsoft/archive/2011/06/02/2067712.html //在任务栏显示 进度条 unit Unit9; interface use ...