Routing 在 MVC 上的应用

Routing简介

ASP.NET Routing可以使您访问一个URL,而该URL不必映射到网站中特定文件。由于 URL 不必映射到文件,所以可以在 Web 应用程序中使用一些描述性的用户操作URL,因此更易于被用户理解。

在一个不使用路由的 ASP.NET 应用程序中,对 URL 的传入请求通常映射到磁盘上的物理文件,如 .aspx 文件。例如,对 http://localhost/Order/OrderItem.aspx?orderId=101 的请求映射到名为 OrderItem.aspx 的文件,该文件包含代码和标记用于呈现对浏览器的响应。网页使用 orderId=101 的查询字符串值来决定显示的内容类型,但是该值对用户可能意义不大。

 

Ps: ASP.Net Routing是一个独立的控件,和MVC本身没有任何关系,只是MVC用Routing来实现对URL的解析和导向。

 

MVC 上应用 Routing

 

1. 简单的路由规则

定义的 URL 模式称作“Routing”。在Routing中,您可以指定占位符,用于从 URL 请求中分析值,然后作具体的映射,还可以指定匹配 URL 请求的常量值。

Routing中,我们可以通过用大括号( { 和 })括住占位符来定义占位符(又称为“URL 参数”)。分析 URL 时将 /  和 . 字符解释为分隔符。将Routing定义中不是分隔符和不在大括号中的值视为一个常量值。将从两个分隔符之间提取的值分配给占位符。

您可以在分隔符之间定义多个占位符,但必须用一个常量值分隔开。例如,{language}-{country}/{action} 是有效的路由模式。而{language}{country}/{action} 则不是一个有效的模式,因为它的占位符之间没有常量或分隔符,因此,路由无法确定在哪里将 language 占位符的值与 country 占位符的值分隔开。

下表演示有效的路由模式和一些与模式匹配的 URL 请求的示例。

路由定义 匹配 URL 示例
{controller}/{action}/{id} /Products/Id/1002
{table}/Details.aspx /Products/Details.aspx
blog/{action}/{entry} /blog/article/123
{reporttype}/{year}/{month}/{day} /sales/2008/1/5
{locale}/{action} /zh-cn/show
{language}-{country}/{action} /zh-cn/show

 

Code:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.Add(new Route
    (
        "Category/{action}/{categoryName}"
        , new CategoryRouteHandler()
    ));
}

 

 

2. 参数的默认值

我们可以设置一个对参数解析的默认值,用作参数在匹配不到时的默认值。

Code:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}", 
        new { controller = "Home", action = "Index", Id = "0" } 
    );

}

 

当URL Routing处理URL Request的时候,上面route定义产生的结果如下表所示: 

URL Parameter values
/Category

controller = "Category"
action = “Index”
Id = “0”

/Category/Product

controller = "Category"
action = "Product"
Id = “0”

/Category/Product/10a

controller = "Category"
action = "Index"
Id = “10a”

3. 不确定个数参数的处理
有时候你需要处理一个URL包含的参数是不确定的URL请求。在你定义route的时候,你可以设置最后一个参数包含一个星号(*),使最后一个参数匹配URL中剩下的参数。例如:

query/{queryname}/{*queryvalues}

当URL Routing处理URL Request的时候,上面route定义产生的结果如下表所示:

URL queryvalues parameter
/query/select/bikes/onsale "bikes/onsale"
/query/select/bikes "bikes"
/query/select Empty string

 

4. 对所要匹配URL的参数添加约束
通过添加约束使URL参数在我们的程序中能更好的工作。废话不多说了,直接看代码:

Code:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.Add(new Route
    (
         "{locale}/{year}"
         , new ReportRouteHandler()
    )
    {
        Constraints = new RouteValueDictionary { { "locale", "{a-z}{2}-{A-Z}{2}" }, { year, @"\d{4}" } }
    });
}

当URL Routing处理URL Request的时候,上面route定义产生的结果如下表所示:

URL Result
/en-US No match. Both locale and year are required.
/en-us/2008 No match. The constraint on locale requires the fourth and fifth characters to be uppercase.
/en-US/08 No match. The constraint on year requires 4 digits.
/en-US/2008 locale = "en-US"
year = "2008"

 


5. 从Routes中创建URL
当你想集中控制逻辑来构造URL时,你可以使用routes来产生URLs。通过传递一个dictionary的参数值给RouteCollection对象的GetVirtualPath方法来创建一个URL。GetVirtualPath方法查找RouteCollection对象中第一个route中跟dictionary匹配的参数,匹配的route被用来产生URL。还是看下面的示例:

下面的示例演示了基于上面的route创建的URL:

Code:

void NavigateUrlDemo ()
{
    HyperLink1.NavigateUrl = RouteTable.Routes.GetVirtualPath(
        context,new RouteValueDictionary {
            { "categoryName", "beverages" },
            {"action", "summarize" }}
    ).VirtualPath;
}


当代码运行的时候,HyperLink1控件将会包含值"Category/summarize/beverages"在NavigateUrl属性中。

示例代码

public static void RegisterRoutes(RouteCollection routes)
{
    routes.Add(
        new Route ("Category/{action}/{categoryName}",
        new CategoryRouteHandler()
    )
    {
        Defaults = new RouteValueDictionary {
        {"categoryName", "food"},
        {"action", "show"}}
    });
}

 

6. 在程序执行时加载

通常情况下,我们在 Global.asax 文件中 Application_Start 事件的处理程序调用的方法中添加路由。这样做可确保应用程序启动时路由已经被注册并可用。还使您能够在对应用程序进行单元测试时直接调用方法。如果您想在对应用程序进行单元测试时直接调用一个注册路由的方法,则必须保证该方法必须是静态的,并且必须具有一个 RouteCollection 参数。

您可以通过将路由添加到 RouteTable 类的静态 Routes 属性来添加路由。Routes 属性是一个 RouteCollection 对象,存储 ASP.NET 应用程序的所有路由。下面的示例演示从 Global.asax 文件中添加一个 Route 对象的代码,该对象定义了名为 action 和 categoryName 的两个 URL 参数。

 

通常,我们在Global.asax文件中的Application_Start事件中添加routes,这确保routes在程序启动的时候就可用,而且也允许在你进行单元测试的时候直接调用该方法。如果你想在单元测试的时候直接调用它,注册该routes的方法必需是静态的同时有一个RouteCollection参数。
下面的示例是Global.asax中的代码,演示了添加一个包含两个URL参数action 和 categoryName的Route对象:

Code:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default",                                              // Route name
        "{controller}/{action}/{id}",                           // URL with parameters
        new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
    );

}

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
}

 

7,测试(=)

参考:

ASP.NET Routing
http://msdn.microsoft.com/en-us/library/cc668201.aspx

ASP.NET MVC URL Routing 学习  *第五部分我从lulu Blog拷贝过来的。同时也推荐一下他的Blog,可以从上面得到很多MVC的资料。

posted @ 2009-02-20 10:56  Binglingshui  阅读(367)  评论(0编辑  收藏  举报
小明明