约束路由

上面我们有一个{id}用来捕获参数的,但是你也发现了它可以捕捉任何字符串等等,但是我们有时需要限制它,比如让它只能输入数字,那么我们就可以使用正则表达式去约束它。

如下修改RouteConfig.cs

 1     public class RouteConfig
2 {
3 public static void RegisterRoutes(RouteCollection routes)
4 {
5 routes.MapRoute(
6 name: "Default",
7 url: "{controller}/{action}/{id}",
8 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
9 constraints: new{id = @"^\d*$"},
10 namespaces: new[] { "MvcStudy.Controllers" }
11 );
12 }
13 }

我们可以清楚的看到我们通过constraints参数将id参数约束为只能输入数字,当然你也可以通过一样的方式去约束其他的参数。通过httpMethod = new HttpMethodConstraint("GET","POST")可以约束该路由只能通过那种方式访问。

如果你的约束是上面无法做到的,那么下面的自定义约束一定会符合你的要求。新建一个自定义的约束只需要创建一个实现IRouteConstraint接口的类即可,比如我们限制只能是谷歌浏览器才能访问,新建一个Filters文件,并新建一个MyRouteConstraint类,写入如下的代码:

1     public class MyRouteConstraint : IRouteConstraint
2 {
3
4 public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
5 {
6 return httpContext.Request.UserAgent.Contains("Chrome");
7 }
8 }

接着我们换到不同的浏览器去测试,就会发现区别了(如果你通过浏览器的开发者工具或者其他工具修改UserAgent的话也可以越过这个约束,如Filddler2工具)

解决与物理路径的冲突

当发送一个请求至ASP.NET MVC时,其实会检查网站中存不存在这个请求的物理路径文件,如果存在的话,就会直接将这个物理文件返回。但是有时候我们需要它执行控制器的某个方法,而不是直接将这个物理文件返回。那么我们就需要这节知识。下面我们先在网站根目录中新建一个 Test.html ,在其中随便写上一些内容,然后访问。再在RouteConfig.cs中写入如下代码:

 1     public class RouteConfig
2 {
3 public static void RegisterRoutes(RouteCollection routes)
4 {
5 routes.RouteExistingFiles = true;
6
7 routes.MapRoute(
8 name: "Default2",
9 url: "Test.html",
10 defaults: new { controller = "Home", action = "List" }
11 );
12 }
13 }

这个时候我们再重新刷新浏览器,那么我们就可以看到控制器返回的结果了,这样我们就解决了物理路径和路由之间的冲突问题了。

8.绕过路由系统

如果我们有一些URL路径不希望通过路由系统,那么我们就可以利用这节知识。

下面是RouteConfig.cs的内容:

 1     public class RouteConfig
2 {
3 public static void RegisterRoutes(RouteCollection routes)
4 {
5 routes.IgnoreRoute("webResources.axd{*pathinfo}");
6
7 routes.MapRoute(
8 name: "Default2",
9 url: "Test.html",
10 defaults: new { controller = "Home", action = "List" }
11 );
12 }
13 }

9.自定义路由系统

如果上面的技术还无法解决你的问题,那么我们下面将会介绍如何自定义路由系统。自定义路由系统只需要继承RouteBase并实现两个方法,如下:

(1):GetRouteData

(2):GetVirtualPath

下面是我写的一个简单示例,用来判断访问者是否是移动设备,如果是移动设备则路由到前缀为M的控制器处理请求,否则返回NULL交由默认的路由

处理,下面为我的源码:

 1 public class CustomRouteBase : RouteBase
2 {
3 private List<String> userAgent;
4
5 public CustomRouteBase(params String[] userAgents)
6 {
7 userAgent = userAgents.ToList();
8 }
9
10 public override RouteData GetRouteData(HttpContextBase httpContext)
11 {
12 RouteData rd = new RouteData(this, new MvcRouteHandler());
13 Regex r = new Regex(@"/(\w+)", RegexOptions.IgnoreCase);
14 MatchCollection mc = r.Matches(httpContext.Request.Path);
15 String agent = httpContext.Request.UserAgent.ToLower();
16 foreach (String item in userAgent)
17 {
18 if (agent.Contains(item))
19 {
20 if (mc.Count >= 2)
21 {
22 rd.Values.Add("controller", "M" + mc[0].Groups[1].Value.ToString());
23 rd.Values.Add("action", mc[1].Groups[1].Value.ToString());
24 }
25 else
26 {
27 rd.Values.Add("controller", "MHome");
28 rd.Values.Add("action", "Index");
29 }
30 return rd;
31 }
32 }
33 return null;
34 }
35
36 public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
37 {
38 return null;
39 }
40 }

最后我们将该自定义路由添加进来(RouteConfig.cs):

 1     public class RouteConfig
2 {
3 public static void RegisterRoutes(RouteCollection routes)
4 {
5 routes.Add(new CustomRouteBase("iphone", "ipad", "android"));
6
7 routes.MapRoute(
8 name: "Default2",
9 url: "Test.html",
10 defaults: new { controller = "Home", action = "List" }
11 );
12 }
13 }

现在你新建一个MHome的控制器,然后访问看看(建议使用Google浏览器,并通过开发者工具改变UserAgent即可快速看到效果)。

10.自定义路由处理程序

或许你会觉得ASP.NET MVC的控制器太麻烦,相比而言有些功能你更希望使用一般处理程序。但是访问的时候必须使用物理路径又发觉麻烦,那么通过学习这节,你将可以将一般处理程序也加入到路由中,并且可控性很强。

首先我们必须新建一个实现IRouteHandler接口的类:

 1     public class DonwloadHandler : IRouteHandler
2 {
3
4 public IHttpHandler GetHttpHandler(RequestContext requestContext)
5 {
6 return new CustomHandler();
7 }
8 }
9
10 public class CustomHandler : IHttpHandler
11 {
12
13 public bool IsReusable
14 {
15 get { return false; }
16 }
17
18 public void ProcessRequest(HttpContext context)
19 {
20 context.Response.Write("download model");
21 }
22 }

你们可以看到上面的源码,我是直接在下面新建了一个实现IHttpHandler的类,并且在GetHttpHandler中将该类的实例返回,当然你还可以在这个方法中进行判断以便根据实际情况交由不同的一般处理程序去处理请求。

下面就是将这个路由处理程序添加到路由中,这里我们映射到MyTest这个路径:

 1     public class RouteConfig
2 {
3 public static void RegisterRoutes(RouteCollection routes)
4 {
5 routes.Add(new Route("MyTest",new DonwloadHandler()));
6
7 routes.MapRoute(
8 name: "Default2",
9 url: "Test.html",
10 defaults: new { controller = "Home", action = "List" }
11 );
12 }
13 }

接着我们访问http://localhost:2392/MyTest就可以看到结果了。

装载:http://www.cnblogs.com/yaozhenfa/

ASP.NET MVC学习之路由篇的更多相关文章

  1. ASP.NET MVC学习之路由篇(3)

    根据路由输出链接 既然是网站开发自然少不了链接,我们已经学会了强大的路由,但是还缺少一步就是能够将这些路由的路径输出到页面,下面我们就开始学习如何输出路由路径. 首先我们的路由注册部分如下所示: 1 ...

  2. ASP.NET MVC学习之路由篇(2)

    7.解决与物理路径的冲突 当发送一个请求至ASP.NET MVC时,其实会检查网站中存不存在这个请求的物理路径文件,如果存在的话,就会直接将这个物理文件返回.但是有时候我们需要它执行控制器的某个方法, ...

  3. ASP.NET MVC学习之路由篇(1)

    1.基本路由 RouteConfig.cs: 1 public class RouteConfig 2 { 3 public static void RegisterRoutes(RouteColle ...

  4. ASP.NET MVC学习之控制器篇

    一.前言 许久之后终于可以继续我的ASP.NET MVC连载了,之前我们全面的讲述了路由相关的知识,下面我们将开始控制器和动作的讲解. ASP.NET MVC学习之路由篇幅(1) ASP.NET MV ...

  5. ASP.NET MVC学习之过滤器篇(2)

    下面我们继续之前的ASP.NET MVC学习之过滤器篇(1)进行学习. 3.动作过滤器 顾名思义,这个过滤器就是在动作方法调用前与调用后响应的.我们可以在调用前更改实际调用的动作,也可以在动作调用完成 ...

  6. ASP.NET MVC学习之控制器篇扩展性

    原文:ASP.NET MVC学习之控制器篇扩展性 一.前言 在之前的一篇随笔中已经讲述过控制器,而今天的随笔是作为之前的扩展. 二.正文 1.自定义动作方法 相信大家在开发过程一定会遇到动作方法的重名 ...

  7. ASP.NET MVC学习之视图篇(2)

    继ASP.NET MVC学习之视图(1)学习 4.HTML辅助器 虽然在ASP.NET MVC中我们已经摆脱了ASP.NET的控件,但是对于页面中需要循环标签的情况依然还是存在,可能很多人认为用for ...

  8. ASP.NET MVC学习之过滤器篇(1)

    一.前言 继前面四篇ASP.NET MVC的随笔,我们继续向下学习.上一节我们学习了关于控制器的使用,本节我们将要学习如何使用过滤器控制用户访问页面. 二.正文 以下的示例建立在ASP.NET MVC ...

  9. ASP.NET MVC学习之控制器篇(二)

    原文链接:http://www.asp.net/learn/mvc/ 这篇教程探索了ASP.NET MVC控制器(controller).控制器动作(controller action)和动作结果(a ...

随机推荐

  1. ios 网络数据下载和JSON解析

    ios 网络数据下载和JSON解析 简介 在本文中笔者将要给大家介绍ios中如何利用NSURLConnection从网络上下载数据,如何解析下载下来的JSON数据格式,以及如何显示数据和图片的异步下载 ...

  2. TCP 和 UDP 协议发送数据包的大小 (转载)

    MTU最大传输单元,这个最大传输单元实际上和链路层协议有着密切的关系,EthernetII帧的结构DMAC+SMAC+Type+Data+CRC由于以太网传输电气方面的限制,每个以太网帧都有最小的大小 ...

  3. php5.5新特性之yield理解

    今天,在阅读别人代码时,其中出现了一个陌生的关键字yield,想一探究竟,于是找到:http://php.net/manual/zh/language.generators.overview.php ...

  4. 安装好ubuntu之后要干的几件事

    安装完ubuntu之后啊,系统除了自带了firefox,libre office等能用,要应付日常需求还差了些.然后我根据最近我的需求写了个清单.完成这个清单就让ubuntu成了一个得心应手的好工具了 ...

  5. Measuring Lengths in Baden

    Description Measuring Lengths in Baden time limit per test: 2 seconds memory limit per test: 256 meg ...

  6. 1010 Area

    题目要求面积和判断非相邻边不相交.和数学和几何有关系. #include <stdio.h> #include <math.h> #define MISS 0.0000001 ...

  7. c# vs2010 winfrom控件检测网络环境

    写下以作备用,代码附上. public partial class UserControl1 : UserControl, IObjectSafety { //检测网络状态 [DllImport(&q ...

  8. MVC4商城项目四:应用Bundle捆绑压缩技术

    从MVC4开始,我们就发现,项目中对Global.asax进行了优化,将原来在MVC3中使用的代码移到了[App_Start]文件夹下,而Global.asax只负责初始化.其中的BundleConf ...

  9. stopWeblogic时提示错误以及无法关闭服务

    执行: y@y:~/oracle/middleware/user_projects/domains/yshy_domain/bin$ ./stopWebLogic.sh 错误信息如下: Stoppin ...

  10. QTableView中嵌入复选框CheckBox 的四种方法总结

    搜索了一下,QTableView中嵌入复选框CheckBox方法有四种: 第一种不能之前显示,必须双击/选中后才能显示,不适用. 第二种比较简单,通常用这种方法. 第三种只适合静态显示静态数据用 第四 ...