五、URL Routing介绍

在这篇文章中我们将介绍ASP.NET MVC程序中的重要的概念――URL路由。URL 路由就是把入站请求映射到指定的MVC控制器动作上
在这篇文章第一部分,我们将学习使用默认路由表把请求映射到控制器动作上。在第二部分,我们将学习修改默认路由表,实现自定义路由。

一、使用默认路由表
当我们创建ASP.NET MVC应用程序的时候,应用程序会自动配置URL路由。URL路由需要通过两个地方进行设置。
第一、 在应用程序的Web.Config文件中启用URL路由。
在配置文件中有四个配置节与URL路由相关:
a) system.web.httpModules
b) system.web.httpHandlers
c) system.webserver.modules
d) system.webserver.handlers
注意不能删除这些配置节,因为没有这些配置节URL路由无法运行。
第二、路由表代码被放在应用程序的Global.asax文件中。
Global.asax文件是一个特殊的文件,它包含了ASP.NET应用程序生命周期中特殊的事件。路由表就是在应用程序启动的时候生成的。
下面是ASP.NET MVC应用程序中的Global.asax文件的代码
Listing 1 – Global.asax.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MyApp
{     
public class GlobalApplication : System.Web.HttpApplication     
{          
  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);          
   }     
}
}
当ASP.NET MVC应用程序第一次运行的时候,Application_Start()方法被调用。这个方法中调用了RegisterRoutes()方法,最后在RegisterRoutes()方法中创建了路由表。
默认路由表中包含了一个URL路由(名子叫作Default),这个Default路由把入站的URL第一部分{controller}映射为控制器名称,第二部分{action}映射为控制器动作,第三部分映射为动作的输入参数,叫做id。
假设我们在浏览器地址栏中输入下列URL
/Home/Index/3
Default路由把URL地址进行如下映射
controller = Home
action = Index
id = 3
当我们在URL地址栏中发出下列请求时
URL /Home/Index/3
会执行HomeController.Index(3)这个控制器方法。

Default路由默认包含上面三个参数,如果我们客户端请求没有指定控制器,那控制器默认为HomeController,如果没有指定动作,那动作默认为Index动作,最后如果没有指定动作的输入参数,那默认的动作输入能数是空字符串。
我们来看一下Default路由如何把URL映射到控制器动作上的。假设我们在浏览器地址栏中输入URL如下:
/Home
因为Default路由有默认的参数,所以这个URL地址会调用HomeController类的Index()方法。

Listing 2 – HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MyApp.Controllers
{     
[HandleError]     
public class HomeController : Controller     
{          
   public ActionResult Index(string Id)          
   {               
    return View();          
   }     
}
}
在上面的代码中,HomeController类包含名子为Index()的方法,它只接收一个参数Id,URL地址/Home默认调用了Index()方法,并向其参数Id传入一个空字符串.
(原创:灰灰虫的家 http://hi.baidu.com/grayworm)
/Home还映射到下面的Index()方法
Listing 3 – HomeController.cs (Index action with no parameter)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MyApp.Controllers
{     
[HandleError]     
public class HomeController : Controller     
{          
   public ActionResult Index()          
   {               
    return View();          
   }     
}
}
这里的Index()方法并不接收任何参数,所以/Home在调用/Home/Index/3的时候也会调用Index()方法,但这时的Id参数会被忽略掉。

/Home还映射到下面的Index()方法
Listing 4 – HomeController.cs (Index action with nullable parameter)
using System;
using System.Collections.Generic;
using System.Linq; using System.Web;
using System.Web.Mvc;
namespace MyApp.Controllers
{     
[HandleError]     
public class HomeController : Controller     
{          
   public ActionResult Index(int? id)          
   {               
    return View();          
   }     
}
}
上面的代码中接收int?型参数,因为此参数是个可为空的参数,所以在调用Index()方法时,不会发生任何异常。

最后如果/Home射到下面的Index()方法,会发生异常信息,因为Index()方法的Id参数是个不可以为空的参数。
Listing 5 – HomeController.cs (Index action with Id parameter)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MyApp.Controllers
{     
[HandleError]     
public class HomeController : Controller     
{          
   public ActionResult Index(int id)          
   {               
    return View();          
   }     
}
}
《图1》
在上面的代码中,/Home/Index/3这种URL地址调用会执行很正常,因为会自动把3传递给参数Id。

 

二、创建自定义路由(原创:灰灰虫的家 http://hi.baidu.com/grayworm)
在大多数的情况下,默认路由会默满足我们的需求,但当遇到一些特殊的需情况下,则需要我们创建我们自己的路由。
假设我们要做一个博客程序,我们需处理的请求URL地址如下:
/Archive/12-25-2009
当用户在客户端输入后,想取根据日期12/25/2009取得博客实体内容,这样就需要我们自定义URL路由。
下面的Global.asax文件包含了一个名子为Blog的自定义的路由,该路由的请求类似于/Archive/entrydate
Listing 6 – Global.asax (with custom route)
using System.Web.Mvc;
using System.Web.Routing;
namespace MyApp
{     
   public class GlobalApplication : System.Web.HttpApplication     
   {          
   public static void RegisterRoutes(RouteCollection routes)          
    {               
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");               
     routes.MapRoute(                    
     "blog",                    
     "Archive/{entryDate}",                    
     new {controller = "Archive", action = "Entry"}                    
     );
               
     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);          
    }     
   }
}
添加路由表的顺序是很重要的。我们自定义的路由表被添加在Default路由之前,如过添加次序倒过来的话,那总会先调用Default路由了。
我们自定义的Blog路由匹配任何以/Archive/开头的请求,因此它能够匹配以下URL
/Archive/12-25-2009
/Archive/10-6-2004
/Archive/apple


自定义路由匹配Archive控制器并触发控制器的Entry()动作。当Entry()动作被调用的时候,日期就被以参数据形式传递Entry()方法。
Blog自定义路由对应的控制器代码如下:
Listing 7 – ArchiveController.cs
using System;
using System.Web.Mvc;
namespace MyApp.Controllers
{     
   public class ArchiveController : Controller     
   {          
   public string Entry(DateTime entryDate)          
    {               
    return "You requested the entry on " + entryDate.ToString();          
    }     
   }
}
上面的代码中,Entry()方法接收一个日期时间型参数ASP.NET MVC框架能够自动把URL地址栏中的日期字符串值转换为日期时间型数据,如果转换失败就会产生异常。

三、总结
这篇文章主要介绍了URL路由,
首先我们测试ASP.NET MVC默认路由。知道了默认路由如何映射控制器动作
然后我们又学习如何创建自定义路由。知道了如何在Global.asax文件中添加自定义路由来操作博客实体。讨论了如何把博客实体请求映射到ArchiveController的Entry()动作上。

posted @ 2012-04-21 14:22  大智若简  阅读(348)  评论(0编辑  收藏  举报