使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【外传】——Attribute Routing
2016-04-03 23:23
1251 查看
原文:
系列导航地址 /article/5667076.html
题外话:由于这个技术点是新学的,并不属于原系列,但借助了原系列的项目背景,故命名外传系列,以后也可能在这个系列中附加一些新的技术。
前言
在Web Api 2.0中,提出了一种新的配置路由方式——基于特性的路由(Attribute-based Routing),在我们之前介绍的配置路由方式称为——基于公约的路由(Convention-based Routing),新的路由配置方式同样应用在MVC5中,因此本文就来介绍一下基于特性的路由。
在之前的一篇文章中,我们处理了这么一个业务——实现学生选课。我们是通过在“WebApiConfig”定制了一条路由数据来实现的,这条路由实现了选课以及根据课程Id来查询选择选择该课程的所有学生信息,感觉设计还可以。在实际应用中一般来说查询用的是最多的,使用Attribute Routing来注册路由会更灵活,控制起来也更方便,更符合Rest。本文以根据课程的名字来查询所有选择该课程的学生信息以及根据课程名字以及学生名字查询某一学生的信息。
基于特性的路由介绍
顾名思义,新路由将使用一个特性来实现路由注册,如下:
这个类包含3个属性:Name指路由的名字,Order是指路由的顺序,Template就是我们要去匹配URL的模板
实现Attribute Routing
原理性的东西不多介绍的(我也没多研究 呵呵),能把学到的技术运用到实际中才是王道,上来一大堆原理容易晕,以后需要深入研究再看原理。
在“EnrollmentsController”中新增一个方法GetStudentsInfo:
在我们的Action上使用了RouteAttribute。分析一下这个URL模板( "api/enrollments/{courseName}/{studentName?} " ),{courseName}会匹配到Action的courseName参数上,对于Action的另一个参数studentName是一个可选参数,也就是说请求中没有给出值那么就是默认的空字符串,有值得话就会被赋值,因此我们在“{studentName}”后面加上? 标记为可选的URI参数。
ok,就这么简单,测试一次:
结果:
呃,出错了。。。
一个新的问题
出错了,不过不管怎么说解决方案总归是有的,首先看下错误原因:是在LearningControllerSelector类的方法中出现了空引用,那么我们就不得不看下这个方法:
看了这段代码我们不难发现这个方法是我们重写了基类的方法,目的是为了实现现版本控制(详情可移步: /article/5667086.html ),在我们重写的方法中我们用到了RouteData中包含的Controller的名字,而这个名字是由基于公约的路由与URI匹配得到的,因此我们这里肯定是没有的。因为我们的项目混合了2钟路由配置,而自定义的方法是针对基于公约的路由配置,因此对于Attribute
Routing我们直接使用默认的选择方式:
在“ var controllerName = routeData.Values[ " controller " ].ToString(); ”代码之前加一个判断:
再次请求就会得到如下结果:
结果正确,解决方案感觉还可以再考虑考虑,大家有什么好的建议可以提。但是不管怎么说,有一点是明确的:对于基于特性的路由规则,不需要包含Controller的名字,在本案列中感觉上是寻找Acton上的路由模板来匹配请求的URI,然后确定对应的Action。
总结
基于特性路由(Attribute Routing)是一种新的定制路由规则方式,与传统的配置方式相比更灵活,但同时比较分散,在web api中,2钟路由配置方式可以共存,所以本文只是介绍一种新的配置方式,做项目时也可以多一种选择。
本文参考相关链接: /article/4711916.html
http://www.cnblogs.com/artech/p/attribute-routing-01.html
源码地址: https://github.com/fzrain/WebApi.eLearning
系列导航地址 /article/5667076.html
题外话:由于这个技术点是新学的,并不属于原系列,但借助了原系列的项目背景,故命名外传系列,以后也可能在这个系列中附加一些新的技术。
前言
在Web Api 2.0中,提出了一种新的配置路由方式——基于特性的路由(Attribute-based Routing),在我们之前介绍的配置路由方式称为——基于公约的路由(Convention-based Routing),新的路由配置方式同样应用在MVC5中,因此本文就来介绍一下基于特性的路由。
在之前的一篇文章中,我们处理了这么一个业务——实现学生选课。我们是通过在“WebApiConfig”定制了一条路由数据来实现的,这条路由实现了选课以及根据课程Id来查询选择选择该课程的所有学生信息,感觉设计还可以。在实际应用中一般来说查询用的是最多的,使用Attribute Routing来注册路由会更灵活,控制起来也更方便,更符合Rest。本文以根据课程的名字来查询所有选择该课程的学生信息以及根据课程名字以及学生名字查询某一学生的信息。
基于特性的路由介绍
顾名思义,新路由将使用一个特性来实现路由注册,如下:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple=true, Inherited=true)] public sealed class RouteAttribute : Attribute, IHttpRouteInfoProvider { public RouteAttribute(); public RouteAttribute(string template); public string Name { get; set; } public int Order { get; set; } public string Template { get; private set; } }
这个类包含3个属性:Name指路由的名字,Order是指路由的顺序,Template就是我们要去匹配URL的模板
实现Attribute Routing
原理性的东西不多介绍的(我也没多研究 呵呵),能把学到的技术运用到实际中才是王道,上来一大堆原理容易晕,以后需要深入研究再看原理。
在“EnrollmentsController”中新增一个方法GetStudentsInfo:
[Route("api/enrollments/{courseName}/{studentName?}")] public IEnumerable<StudentBaseModel> GetStudentsInfo(string courseName, string studentName="") { IQueryable<Student> query; Course course= TheRepository.GetAllCourses().Where(c => c.Name == courseName).FirstOrDefault(); if (course==null ) { return null ; } query = TheRepository.GetEnrolledStudentsInCourse(course.Id).OrderBy(s => s.LastName); if (!string.IsNullOrWhiteSpace(studentName)) { query = query.Where(s => s.FirstName == studentName); } var totalCount = query.Count(); System.Web.HttpContext.Current.Response.Headers.Add("X-InlineCount", totalCount.ToString()); var results = query .ToList() .Select(s => TheModelFactory.Create(s)); return results; }
在我们的Action上使用了RouteAttribute。分析一下这个URL模板( "api/enrollments/{courseName}/{studentName?} " ),{courseName}会匹配到Action的courseName参数上,对于Action的另一个参数studentName是一个可选参数,也就是说请求中没有给出值那么就是默认的空字符串,有值得话就会被赋值,因此我们在“{studentName}”后面加上? 标记为可选的URI参数。
ok,就这么简单,测试一次:
结果:
呃,出错了。。。
一个新的问题
出错了,不过不管怎么说解决方案总归是有的,首先看下错误原因:是在LearningControllerSelector类的方法中出现了空引用,那么我们就不得不看下这个方法:
public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { var controllers = GetControllerMapping(); //Will ignore any controls in same name even if they are in different namepsace var routeData = request.GetRouteData(); var controllerName = routeData.Values["controller"].ToString(); HttpControllerDescriptor controllerDescriptor; if (controllers.TryGetValue(controllerName, out controllerDescriptor)) { var version = "2"; var versionedControllerName = string.Concat(controllerName, "V", version); HttpControllerDescriptor versionedControllerDescriptor; if (controllers.TryGetValue(versionedControllerName, out versionedControllerDescriptor)) { return versionedControllerDescriptor; } return controllerDescriptor; } return null; }
看了这段代码我们不难发现这个方法是我们重写了基类的方法,目的是为了实现现版本控制(详情可移步: /article/5667086.html ),在我们重写的方法中我们用到了RouteData中包含的Controller的名字,而这个名字是由基于公约的路由与URI匹配得到的,因此我们这里肯定是没有的。因为我们的项目混合了2钟路由配置,而自定义的方法是针对基于公约的路由配置,因此对于Attribute
Routing我们直接使用默认的选择方式:
在“ var controllerName = routeData.Values[ " controller " ].ToString(); ”代码之前加一个判断:
if (string.IsNullOrWhiteSpace(routeData.Route.RouteTemplate)) { return base.SelectController(request); }
再次请求就会得到如下结果:
结果正确,解决方案感觉还可以再考虑考虑,大家有什么好的建议可以提。但是不管怎么说,有一点是明确的:对于基于特性的路由规则,不需要包含Controller的名字,在本案列中感觉上是寻找Acton上的路由模板来匹配请求的URI,然后确定对应的Action。
总结
基于特性路由(Attribute Routing)是一种新的定制路由规则方式,与传统的配置方式相比更灵活,但同时比较分散,在web api中,2钟路由配置方式可以共存,所以本文只是介绍一种新的配置方式,做项目时也可以多一种选择。
本文参考相关链接: /article/4711916.html
http://www.cnblogs.com/artech/p/attribute-routing-01.html
源码地址: https://github.com/fzrain/WebApi.eLearning
相关文章推荐
- ASP.NET MVC5 新特性:Attribute路由使用详解
- ASP.NET MVC:自定义 Route 让你的 Url 更优雅
- ASP.NET MVC:自定义 Route 生成小写 Url
- 史上最全的ASP.NET MVC路由配置,以后RouteConfig再弄不懂神仙都难救你啦
- asp.net获取服务器信息
- ASP.Net后台 实现先弹出对话框,再跳转到另一个网页的实现方法
- Spring的<aop:aspectj-autoproxy>配置
- win7+iis7+asp+.net+php环境配置
- ASP.NET MVC EF 02 数据库访问层的设计
- 【dotnet跨平台】最新版dotnet-cli下的ASP.NET Core和asp.net mvc【RC2尝鲜】
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第二篇:第一个页面
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作
- 动画队列,第一个动画的字体变大和第二个动画的元素高度增加同时进行,两个动画完成之后,才触发第3个动画
- ASP.NET生成验证码
- 【java】解决JDK出现Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=gasp的问题
- 个人网站实现扫码登录asp.net 扫码登录
- asp.net MVC控制器返回json问题总结
- asp 后台获取 input 的值
- ASP.NET MVC HtmlHelper之Html.ActionLink
- ssh整合context:component-scan包名写了*号:Failed to parse configuration class [org.springframework.cache.aspectj.AspectJJCacheConfiguration]