【转】ASP.NET MVC3路由

MVC系列文章:http://www.cnblogs.com/QLeelulu/archive/2008/10/05/1303997.html

第一部分

转自:http://www.cnblogs.com/QLeelulu/archive/2008/10/03/1303612.html

在一个route中,通过在大括号中放一个占位符来定义( { and } )。当解析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在程序启动的时候就可用,而且也允许在你进行单元测试的时候直接调用该方法。如果你想在单元测试的时候直接调用它,注册该routes的方法必需是静态的同时有一个RouteCollection参数。
下面的示例是Global.asax中的代码,演示了添加一个包含两个URL参数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}",                           // 带有参数的URL

        new { controller = "Category", action = "Index", categoryName = "4mvc" }  // 设置默认的参数

    ); 



} 



protected void Application_Start()

{

    //在程序启动的时候注册我们前面定义的Route规则

    RegisterRoutes(RouteTable.Routes);

}

 

在这里我不打算再详细去讲解。以下只是简单的说明一下。

忽略对某类URL的Routing:

 //忽略对.axd文件的Route,也就是和WebForm一样直接去访问.axd文件
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

 

添加约束条件,支持正则表达式。例如我们需要对id参数添加一个必须为数字的条件:

routes.MapRoute(
    "Default",                                              
    "{controller}/{action}/{id}",                           
    new { controller = "Home", action = "Index", id = "" },  
    new { id = @"[\d]*" } //id必须为数字
); 

 

使用星号(*)匹配不确定个数的参数,这会匹配URL后面所有的剩余的参数。例如:

query/{queryname}/{*queryvalues}

对于url:query/aspnetmvc/preview5/routing ,则queryvalues参数匹配的参数为 preview5/routing。

url匹配Route是根据Route的定义顺序来自上而下匹配的。例如我们定义两个Route:

public static void RegisterRoutes(RouteCollection routes)

{

    routes.MapRoute(

        "Default",                                              // Route 的名称

        "{controller}/{action}/{id}",                           // 带有参数的URL

        new { controller = "Home", action = "Index", id = "" }  // 设置默认的参数

    );

    routes.MapRoute(

        "Post",

        "Post/{id}",

        new { controller = "Post", action = "Index", id = "" }

    );

}

不知你看出上面定义的两个Route有什么问题没有?我想你看出来了,URL永远都匹配不了第二个Route,也就是名为Post的Route,因为能匹配第二个Route的url一样也能匹配第一个Route,而url匹配Route是根据Route的定义顺序来自上而下匹配的,所以URL永远都匹配不了第二个Route。所以,在定义Route的时候,要将一些特别的Route放到前面。

如果你要将ASP.NET MVC部署到IIS6下面,由于IIS6对于http://blog.51mvc.com/index这类没有扩展名的URL是不会交由ASP.NET的aspnet_isapi.dll处理的,所以你的ASP.NET MVC程序部署到IIS6的时候可能会出现404错误。你可以为你的ASP.NET MVC站点添加一个通配符:

然后点击"通配符应用程序映射"下的"插入"按钮,在弹出的对话框中如下设置:

 

你如果担心添加通配符会给出现性能上的问题,那么你可以修改Route为带扩展名的,这个扩展名是完全由你自己定义的,例如我们使用4mvc来做url的扩展名:

routes.MapRoute(
    "Default",                                              // Route 的名称
    "{controller}.4mvc/{action}/{id}",                           // 带有参数的URL
    new { controller = "Home", action = "Index", id = "" }  // 设置默认的参数
); 

然后再在IIS6中添加这个扩展名的映射:

 

然后我们访问的URL类似于:http://blog.51mvc.com/Home.4mvc/index

 

 

 

第二部分

转自:http://my.oschina.net/xiaolinzi/blog/42608

设置URL路由 

URL路径中,大括号{}内部的代表参数。/作为分割符,不再大括号内的则作为常量。值得注意的是,{controller}和{action}作为2个关键字由MVC路由控制,如果确实需要用这个名字命名参数,可以在前面加上@,例如{@action}。 

默认的设置路由在Global.asax文件中 

public static void RegisterRoutes(RouteCollection routes)方法 

routes.MapRoute( 

                "Default", // Route name 

                "{controller}/{action}/{id}", // URL with parameters 

                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 

            ); 

new { controller = "Home", action = "Index", id = UrlParameter.Optional }是MapRoute中的默认值,意思就是什么都不输入的时候,controller的值和action的值也是必须有值的。 

controller代表控制器,action代表这个控制器中的方法。必须要指定默认的controller和action,不然会报错。 

 routes.MapRoute( 

                "Default", // Route name 

                "{controller}/{action}/{id}", // URL with parameters 

                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 

            ); 

实际上是以下方法的一种简写形式: 

Route myRoute = new Route("{controller}/{action}/{id}", new MvcRouteHandler()) 



Defaults = new RouteValueDictionary( new { 

controller = "Home", action = "Index", id = UrlParameter.Optional 

}) 

}; 

routes.Add("Default", myRoute); 

路由的顺序也是十分重要,URL被一次匹配每个路由模式,一旦匹配成功,就不再继续匹配下去。这点要注意。例如: 

routes.MapRoute( 

"Default", // Route name 

"{controller}/{action}/{id}", // URL with parameters 

new { controller = "Home", action = "Index", // Parameter defaults 

id = UrlParameter.Optional } 

); 

routes.MapRoute( 

"Specials", // Route name 

"DailySpecials/{date}", // URL with parameters 

new { controller = "Catalog", action = "ShowSpecials" } // Parameter defaults 

); 

这里的Specials将不会被匹配到。 

URL路由匹配的时候只匹配路径部分,域名和QueryString不会被匹配到。 

路由约束 

可以使用正则表达式对参数进行验证约束 

routes.Add(new Route("Articles/{id}", new MvcRouteHandler()) 



Defaults = new RouteValueDictionary( 

new { controller = "Articles", action = "Show" } 

), 

Constraints = new RouteValueDictionary(new { id = @"\d{1,6}",id22=@"\d{1,6}" }) 

}); 

上面部分可以简写为如下代码: 

routes.MapRoute(null, "Articles/{id}", 

new { controller = "Articles", action = "Show" }, 

new { id = @"\d{1,6}",id22=@"\d{1,6}" } 

); 

不定长度的路径 

使用*号匹配不定长度。 

  

routes.MapRoute(null, "Articles/{*articlePath}", 

new { controller = "Articles", action = "Show" } 

); 

可以匹配/Articles/Science/Paleontology/Dinosaurs/Stegosaurus 

  

匹配硬盘上的文件 

尽管设置了路由,但是如果在一些特殊的情况下,硬盘上真实存在的文件和路由的URL一致,这时系统会处理硬盘真实存在的文件,而无视路由的存在。 

要解决这个问题,使得无论是否匹配了真实存在的文件,都按照路由的URL来处理,应该在Application_Start()中如下写: 

protected void Application_Start() 

        { 

            AreaRegistration.RegisterAllAreas(); 

            RouteTable.Routes.RouteExistingFiles = true; 

            RegisterRoutes(RouteTable.Routes); 

        } 

RouteTable.Routes.RouteExistingFiles默认是false。 

这样设置了,就算文件真实存在都会按照路由的方式处理。除了下面2种情况: 

1.没有任何匹配的路由。则仍然按照真实文件处理。 

2.使用了IgnoreRoute(),无视了一些路由。 

 

posted @ 2014-05-28 17:27  伯箫  阅读(199)  评论(0)    收藏  举报