繼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就可以看到結果了。