ASP.NET 路由系统
2013-01-25 11:48
429 查看
asp.net 的url路由系统,最初是为了实现Url与物理文件路径的分离而建立的,后来的asp.net mvc也是对asp.net路由系统的扩展,将url与物理文件映射转为url与目标controller/action的映射。
场景:一个页面展示员工列表,点击员工姓名显示员工详细信息
RouteCollection
对现有文件路由
注册路由:
weather页面用来展示当前RouteData的各项属性,当直接请求http://.../weather.aspx时,页面的RouteData各项属性都为空,所以ASP.NET没有对请求地址实施路由
解决方案:在注册路有前加上一句:RouteTable.Routes.RouteExistingFiles=true;这句话是说需要对存在的物理文件实施路由,也就是说如果请求的URL与某个物理文件的路径地址一致的情况下是否还需要对其实施路由,该属性默认值为false,
注册路由忽略地址
但问题出现了,我们在页面weather.aspx引用了样式Style.css,采用RouteExistingFiles=true,意味着Style.css访问也会被路由,然后导向weather.aspx这个页面,这样一来无法正常在页面引用js和css文件了。
解决方案:
在注册路由之前加上一句:RouteTable.Routes.Ignore("{filename}.css/{*pathInfo}");,但是这句话必须在路由注册之前执行。
直接添加路由对象
我们调用RouteCollection对象的MapPageRoute方法进行路由注册的本质是在路由字典中添加Route,所以我们可以自己手工Add一个Route对象,
通过注册URL模版与物理文件的匹配实现请求地址和物理地址的分离
通过注册的路由规则生成一个响应的URL,通过RouteCollection的GetVirtualPath方法来实现
GetVirtualPath方法
如果requestContext参数为null,这种情况会基于当前HTTP上下文(对应HttpContext的静态属性Current)创建一个RequestContext对象作为GetVirtualPath的参数。如果RouteData为空,则抛出异常
路由对象针对GetVirtualPath方法而进行的路由匹配只要求URL模版中定义的变量的值都能被提供,这些变量值具有3个来源:
路由对象定义的默认变量值
指定RequestContext的RouteData提供的变量值(Values属性)
手工提供的变量值(通过values参数指定的RouteValueDictionary对象)
1.请求的URL与物理文件的分离
简单通过一个Demo来演示:场景:一个页面展示员工列表,点击员工姓名显示员工详细信息
RouteCollection
public class RouteCollection : Collection<RouteBase> { //其他成员 //返回有关集合中与指定值匹配的路由的信息 public RouteData GetRouteData(HttpContextBase httpContext); //如果具有指定的上下文和参数值,则返回与路由关联的 URL 路径的相关信息 public VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values); //如果具有指定的上下文、路由名称和参数值,则返回与命名路由关联的 URL 路径的相关信息 public VirtualPathData GetVirtualPath(RequestContext requestContext, string name, RouteValueDictionary values); //定义不需检查是否匹配路由的 URL 模式 public void Ignore(string url); /***eg: 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); } */ //定义一个 URL 模式,此模式在请求 URL 满足指定约束的情况下不需要检查 URL 是否与路由匹配 public void Ignore(string url,Object constraints); //eg:routes.Ignore("{*allaspx}", new {allaspx=@".*\.aspx(/.*)?"}); //提供用于定义 Web 窗体应用程序的路由的方法 public Route MapPageRoute( string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens ); /* * routes.MapPageRoute("ExpenseDetailRoute", "ExpenseReportDetail/{locale}/{year}/{*queryvalues}", "~/expenses.aspx", false, new RouteValueDictionary { { "locale", "US" }, { "year", DateTime.Now.Year.ToString() } }, new RouteValueDictionary { { "locale", "[a-z]{2}" }, { "year", @"\d{4}" } }, new RouteValueDictionary { { "account", "1234" }, { "subaccount", "5678" } }); */ }
对现有文件路由
注册路由:
protected void Application_Start(object sender, EventArgs e) { var defaults = new RouteValueDictionary { { "areacode", "010" }, { "days", 2 }}; var dataTokens = new RouteValueDictionary { { "defaultCity", "BeiJing" }, { "defaultDays", 2 } }; RouteTable.Routes.MapPageRoute("default", "{areacode}/{days}","~/weather.aspx", false, defaults, null, dataTokens); }
weather页面用来展示当前RouteData的各项属性,当直接请求http://.../weather.aspx时,页面的RouteData各项属性都为空,所以ASP.NET没有对请求地址实施路由
解决方案:在注册路有前加上一句:RouteTable.Routes.RouteExistingFiles=true;这句话是说需要对存在的物理文件实施路由,也就是说如果请求的URL与某个物理文件的路径地址一致的情况下是否还需要对其实施路由,该属性默认值为false,
注册路由忽略地址
但问题出现了,我们在页面weather.aspx引用了样式Style.css,采用RouteExistingFiles=true,意味着Style.css访问也会被路由,然后导向weather.aspx这个页面,这样一来无法正常在页面引用js和css文件了。
解决方案:
在注册路由之前加上一句:RouteTable.Routes.Ignore("{filename}.css/{*pathInfo}");,但是这句话必须在路由注册之前执行。
直接添加路由对象
我们调用RouteCollection对象的MapPageRoute方法进行路由注册的本质是在路由字典中添加Route,所以我们可以自己手工Add一个Route对象,
//路由注册方式1 routes.MapPageRoute("ExpenseDetailRoute", "ExpenseReportDetail/{locale}/{year}/{*queryvalues}", "~/expenses.aspx", false, new RouteValueDictionary { { "locale", "US" }, { "year", DateTime.Now.Year.ToString() } }, new RouteValueDictionary { { "locale", "[a-z]{2}" }, { "year", @"\d{4}" } }, new RouteValueDictionary { { "account", "1234" }, { "subaccount", "5678" } }); //路由注册方式2 Route route=new Route("ExpenseReportDetail/{locale}/{year}/{*queryvalues}", new RouteValueDictionary { { "locale", "US" }, { "year", DateTime.Now.Year.ToString() } }, new RouteValueDictionary { { "locale", "[a-z]{2}" }, { "year", @"\d{4}" } }, new RouteValueDictionary { { "account", "1234" }, { "subaccount", "5678" } }, new PageRouteHandler("~/expenses.aspx",false)); RouteTable.Routes.Add("default",route);
2.根据路由规则生成URL
ASP.NET的路由系统主要有两个方面的应用通过注册URL模版与物理文件的匹配实现请求地址和物理地址的分离
通过注册的路由规则生成一个响应的URL,通过RouteCollection的GetVirtualPath方法来实现
public class RouteCollection : Collection<RouteBase> { //其他成员.. //如果具有指定的上下文和参数值,则返回与路由关联的 URL 路径的相关信息 public VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values); //如果具有指定的上下文、路由名称和参数值,则返回与命名路由关联的 URL 路径的相关信息 public VirtualPathData GetVirtualPath(RequestContext requestContext, string name, RouteValueDictionary values); }
GetVirtualPath方法
如果requestContext参数为null,这种情况会基于当前HTTP上下文(对应HttpContext的静态属性Current)创建一个RequestContext对象作为GetVirtualPath的参数。如果RouteData为空,则抛出异常
路由对象针对GetVirtualPath方法而进行的路由匹配只要求URL模版中定义的变量的值都能被提供,这些变量值具有3个来源:
路由对象定义的默认变量值
指定RequestContext的RouteData提供的变量值(Values属性)
手工提供的变量值(通过values参数指定的RouteValueDictionary对象)
public class RouteCollection : Collection<RouteBase> { //其他成员.. //如果具有指定的上下文和参数值,则返回与路由关联的 URL 路径的相关信息 public VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values); //如果具有指定的上下文、路由名称和参数值,则返回与命名路由关联的 URL 路径的相关信息 public VirtualPathData GetVirtualPath(RequestContext requestContext, string name, RouteValueDictionary values); }
protected void Page_Load(object sender,EventArgs e) { //1.指定RequestContext的RouteData提供的Values属性 RouteData routeData =new RouteData(); routeData.Values.Add("areaCode","010"); routeData.Values.Add("days","2"); //封装到RequestContext中 RequestContext requestContext=new RequestContext(); //包装当前HttpContext requestContext.HttpContext =new HttpContextWrapper(HttpContext.Current); requestContext.RouteData=routeData; //2.手工指定参数values RouteValueDictionary values=new RouteValueDictionary(); values.Add("areaCode","028"); values.Add("days","3"); Reponse.Write(RouteTable.Routes.GetVirtualPath(null,null).VirtualPath);//输出注册路有时指定的默认路由值 Reponse.Write(RouteTable.Routes.GetVirtualPath(requestContext,null).VirtualPath);//输出:/010/2 Reponse.Write(RouteTable.Routes.GetVirtualPath(requestContext,values).VirtualPath);//输出:/028/3 }
相关文章推荐
- 理解ASP.NET MVC的路由系统
- ASP.NET路由系统实现原理:HttpHandler的动态映射
- ASP.NET Core的路由[2]:路由系统的核心对象——Router
- ASP.NET路由系统实现原理:HttpHandler的动态映射
- ASP.NET的路由系统:路由映射
- ASP.NET的路由系统:根据路由规则生成URL
- ASP.NET MVC路由系统的核心对象介绍
- ASP.NET MVC 路由系统
- ASP.NET Web API路由系统:路由系统的几个核心类型
- ASP.NET的路由系统:路由映射
- ASP.NET路由系统实现原理:HttpHandler的动态映射
- ASP.NET Web API路由系统:Web Host下的URL路由
- ASP.NET的路由系统:路由映射
- 用路由系统生成输出URL 在视图中生成输出URL 高级路由特性 精通ASP-NET-MVC-5-弗瑞曼
- ASP.NET的路由系统:URL与物理文件的分离
- ASP.NET Web API路由系统:Web Host下的URL路由
- ASP.NET的路由系统:URL与物理文件的分离
- ASP.NET路由系统实现原理:HttpHandler的动态映射
- ASP.NET的路由系统:根据路由规则生成URL
- 创建自定义路由处理程序(Creating a Custom Route Handler) | 定制路由系统| 高级路由特性 |精通ASP-NET-MVC-5-弗瑞曼