ASP.NET MVC 入門3、Routing
本系列文章基于Microsoft ASP.NET MVC Beta.
在一個route中,通過在大括號中放一個占位符來定義( { and } )。當(dāng)解析URL的時候,符號"/"和"."被作為一個定義符來解析,而定義符之間的值則匹配到占位符中。route定義中不在大括號中的信息則作為常量值。下面是一些示例URL:
Valid route definitions Examples of matching URL:
{controller}/{action}/{id} /Products/show/beverages
{table}/Details.aspx /Products/Details.aspx
blog/{action}/{entry} /blog/show/123
{reporttype}/{year}/{month}/{day} /sales/2008/1/5
通常,我們在Global.asax文件中的Application_Start事件中添加routes,這確保routes在程序啟動的時候就可用,而且也允許在你進(jìn)行單元測試的時候直接調(diào)用該方法。如果你想在單元測試的時候直接調(diào)用它,注冊該routes的方法必需是靜態(tài)的同時有一個RouteCollection參數(shù)。下面的示例是Global.asax中的代碼,演示了添加一個包含兩個URL參數(shù)action 和 categoryName的Route對象:
public static void RegisterRoutes(RouteCollection routes){ //忽略對.axd文件的Route,也就是和WebForm一樣直接去訪問.axd文件 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Category", // Route 的名稱 "Category/{action}/{categoryName}", // 帶有參數(shù)的URL new { controller = "Category", action = "Index", categoryName = "4mvc" } // 設(shè)置默認(rèn)的參數(shù) ); } protected void Application_Start(){ //在程序啟動的時候注冊我們前面定義的Route規(guī)則 RegisterRoutes(RouteTable.Routes);}
更多文章請參考:
? System.Web.Routing入門及進(jìn)階 下篇 By 重典
? System.Web.Routing入門及進(jìn)階 上篇 By 重典
? ASP.NET MVC URL Routing 學(xué)習(xí) By Q.Lee.lulu
? ASP.NET Routing (官方文檔)
在這里我不打算再詳細(xì)去講解。以下只是簡單的說明一下。
忽略對某類URL的Routing:
//忽略對.axd文件的Route,也就是和WebForm一樣直接去訪問.axd文件 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
添加約束條件,支持正則表達(dá)式。例如我們需要對id參數(shù)添加一個必須為數(shù)字的條件:
routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = "" }, new { id = @"[d]*" } //id必須為數(shù)字);
使用星號(*)匹配不確定個數(shù)的參數(shù),這會匹配URL后面所有的剩余的參數(shù)。例如:
query/{queryname}/{*queryvalues}
對于url:query/aspnetmvc/preview5/routing ,則queryvalues參數(shù)匹配的參數(shù)為 preview5/routing。
url匹配Route是根據(jù)Route的定義順序來自上而下匹配的。例如我們定義兩個Route:
public static void RegisterRoutes(RouteCollection routes){ routes.MapRoute( "Default", // Route 的名稱 "{controller}/{action}/{id}", // 帶有參數(shù)的URL new { controller = "Home", action = "Index", id = "" } // 設(shè)置默認(rèn)的參數(shù) ); routes.MapRoute( "Post", "Post/{id}", new { controller = "Post", action = "Index", id = "" } );}
不知你看出上面定義的兩個Route有什么問題沒有?我想你看出來了,URL永遠(yuǎn)都匹配不了第二個Route,也就是名為Post的Route,因?yàn)槟芷ヅ涞诙€Route的url一樣也能匹配第一個Route,而url匹配Route是根據(jù)Route的定義順序來自上而下匹配的,所以URL永遠(yuǎn)都匹配不了第二個Route。所以,在定義Route的時候,要將一些特別的Route放到前面。
如果你要將ASP.NET MVC部署到IIS6下面,由于IIS6對于http://blog.51mvc.com/index這類沒有擴(kuò)展名的URL是不會交由ASP.NET的aspnet_isapi.dll處理的,所以你的ASP.NET MVC程序部署到IIS6的時候可能會出現(xiàn)404錯誤。你可以為你的ASP.NET MVC站點(diǎn)添加一個通配符:
然后點(diǎn)擊"通配符應(yīng)用程序映射"下的"插入"按鈕,在彈出的對話框中如下設(shè)置:
你如果擔(dān)心添加通配符會給出現(xiàn)性能上的問題,那么你可以修改Route為帶擴(kuò)展名的,這個擴(kuò)展名是完全由你自己定義的,例如我們使用4mvc來做url的擴(kuò)展名:
routes.MapRoute( "Default", // Route 的名稱 "{controller}.4mvc/{action}/{id}", // 帶有參數(shù)的URL new { controller = "Home", action = "Index", id = "" } // 設(shè)置默認(rèn)的參數(shù));
然后再在IIS6中添加這個擴(kuò)展名的映射:
然后我們訪問的URL類似于:http://blog.51mvc.com/Home.4mvc/index
群上有些朋友說希望教程能根據(jù)一個示例程序來寫,那樣更容易他們的學(xué)習(xí)。所以這里就寫一個Blog的示例程序,為了方便,Model就直接使用Blogengine的業(yè)務(wù)實(shí)體部分。在這里我們先定義這個blog的Route:
BlogRoutepublic static void RegisterRoutes(RouteCollection routes){ //忽略對.axd文件的Route,也就是和WebForm一樣直接去訪問.axd文件 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Admin", "Admin/{action}", new { controller = "Admin", action = "Index" } ); routes.MapRoute( "PostById", "Post/{id}", new { controller = "Home", action = "Post", id = "" }, new { id = @"[d]+" } ); routes.MapRoute( "PostBySlug", "Post/{slug}", new { controller = "Home", action = "Post" } ); routes.MapRoute( "Default", // Route 的名稱 "{controller}/{action}/{id}", // 帶有參數(shù)的URL new { controller = "Home", action = "Index", id = "" } // 設(shè)置默認(rèn)的參數(shù) ); }