代码改变世界

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

2014-03-18 16:11  y-z-f  阅读(7055)  评论(9编辑  收藏  举报

ASP.NET MVC学习之路由篇(1)后继续学习。

 

7.解决与物理路径的冲突

      当发送一个请求至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就可以看到结果了。