在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
ASP.NET路由[ASP.NET Routing]ASP.NET路由允许你在使用URL时不必匹配到网站中具体的文件,因为这个URL不必匹配到一个文件,你使用了描述用户行为且更容易被用户理解的URL。 ASP.NET MVC框架和ASP.NET动态数据(Dynamic Data)扩展路由为MVC应用和动态数据应用增加了特色。 在不使用路由的ASP.NET应用中,一个新的请求会被映射到一个物理文件并由该文件处理这个请求,例如一个.aspx文件。例如,如下请求http://server/application/Products.aspx?id=4会题映射到一个包含代码和标签来向浏览器渲染响应的Products.aspx文件。Web页面人员使用id=4的查询字符来确定显示的内容。 使用ASP.NET路由,你可以定义映射请求-处理程序(request-handler)文件的URL模式,但没必要在将这些文件的名字包含在这个URL中。除此之外,你还可以通过在URL模式中使用占位符来向请求处理程序传输变量数据,而不必使用查询字符串。 例如,如下请求 http://server/application/Products/show/beverages,路由分析器会向页面处理器传入Products,show,beverages这些值。在这个例子中,如果使用server/application/{area}/{action}/{category}URL模式定义路由,页面处理器将会收到一个字典集合,这个集合中包含以下键值对,area:Products,action:show,category:beverages。如果是在一个不被URL路由管理的请求中,/Products/show/beverages片断将会被当作应用中的一个文件路径解释执行。 一、 路由[Routes]路由是被处理程序映射的URL模式。处理程序可以是一个物理文件,例如Web Form应用中的.aspx文件。处理也可以是处理请求的类,例如MVC应用中的控制器。为了定义一个路由,你需要创建一个Route类的实例来指定URL模式,处理程序和可选的路由名称。 你需要给RouteTable类的Routes静态属性添加Route对象来为应用添加路由。Routes属性是一个RouteCollection对象,其中存放着应用中所有路由规则。 你通常没有必要为MVC应用编写代码添加来添加路由规则。Visual Studio的MVC项目模板包含了预配置的URL路由规则。他们定义在MvcApplication类,这个类在Global.asax文件中。 二、 URL模式[URL Patterns]一个URL模式可以包含字面值(literal)和可变的占位符(参考URL参数)。这些字面值和占位符在URL片断中通过斜线(/)字符来分开和定位。 当一个请求到达,这个URL被解析成片断和占位符,这些变量会提供给请求处理器。这个过程和将数据通过查询字符串(query strings)中解析和传输至请求处理器很类似。这两种情况下变量信息都会包含在URL中并传到处理程序的键值对的表单中。对于查询字符串而言,所有键(keys)和值(values)都包含在URL中。对于路由方式,所有键就是在URL模式中定义的占位符名称,只有值包含中URL中。 在一个URL模式中,你定义的占位符被大括号包裹起来({and})。你可以在一个片断中定义多个占位符,但是它们必须被字面值分隔开。例如,{language}-{country}/{action}就是一个合法的路由模式。然而{language}{country}/{action}不是一个合法的路由模式,因为它们的占位符之间缺少字面值或分隔符。因此,路由无法确定language和country占位符的值是何处分隔。 下表给出了合法的路由模式,以及其各自能正确匹配的URL请求。
MVC应用中标准的URL模式[Typical URL Patterns in MVC Applications]在MVC应用中,路由标准的URL模式包含{controller}和 {action}占位符。 当接收到一个请求时,它先被发送到UrlRoutingModule对象,再发送到MvcHandler HTTP处理程序。MvcHandler HTTP处理程序确定需要执行的控制器,通过给URL中的controller值添加”Controller”后缀从而确定将处理本次请求的控制器类型名称。URL中的action值确定调用的处理方法。 例如,URL路径 /Products会被映射成ProductsController控制器。action参数的值是被调用的处理方法的名称。URL路径/Products/show的映射结果将会是调用类ProductsController 的方法Show。 下表给出了默认的URL模式和它们能处理的URL请求示例。
路由使用模式 {resource}.axd/{*pathInfo} 来阻止对网络文件的请求,例如WebReource.axd,ScriptResource.axd被传递给一个控制器。 对于IIS7.0,可以不用扩展名。对于IIS6.0,你必须将扩展名.mvc添加到URL模式,如下所示:{controller}.mvc/{action}/{id} 三、 为Web Forms应用程序添加路由[Add Routes to a Web Forms Application]在Web Form应用中,你可以使用类RouteCollection的方法MapPageRoute(String, String, String) 创建路由。方法MapPageRoute创建Route对象并将其添加RouteCollection对象中。你需要为Route对象在参数在指定一些属性,用来传给方法MapPageRoute。 通常情况下,你在方法中添加的路由会被Global.asax文件中Application_Start 方法处理器调用。这种方法确保了这些路由在应用程序启动时可以正常调用。它也允许你在为应用程序做单元测试时可直接调用该方法。当你在做单元测试时如果想要直接调用一个方法,该方法在注册时就必须是静态(Visual Basic中Shared)且有一个RouteCollection参数。 下例中演示了Global.asax文件中添加一个Route对象,该对象定义了action和categoryName两个参数。URL中还定义了一个被定向到名为Categories.aspx的物理页面。 protected void Application_Start(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); } public static void RegisterRoutes(RouteCollection routes) { routes.MapPageRoute("", "Category/{action}/{categoryName}", "~/categoriespage.aspx"); } 四、 为MVC应用程序添加路由[Adding Routes to an MVC Application]在MVC应用程序中,如果你采用MVC实现控制器的约定,即派生自类ControllerBase且以“Controller”结尾命名,那么你根本不需要搬运添加路由。预配置的路由将会执行你实现的控制器类中的处理方法。 如果你希望在MVC应用程序中添加自定义的路由,你可以使用方法MapRoute(RouteCollection, String, String) 来取代方法MapPageRoute(String, String, String)。 下面示例中演示在Global.asax文件中创建默认MVC路由的代码,即是Visual Studio中MVC应用程序的项目模板。 public class MvcApplication : 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); } } 五、 为URL参数设置默认值[Setting Default Values for URL Parameters]当你定义一个路由时,你可以为参数指定一个默认值。如果一个参数的值不在URL中,则使用默认值。给路由设置默认值时是给类Route的属性Defaults指定一个字典对象。下例演示了如何使用方法MapPageRoute(String, String, String, Boolean, RouteValueDictionary)添加一个包含默认值的路由。 void Application_Start(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); } public static void RegisterRoutes(RouteCollection routes) { routes.MapPageRoute("", "Category/{action}/{categoryName}", "~/categoriespage.aspx", true, new RouteValueDictionary {{"categoryName", "food"}, {"action", "show"}}); } 下图中演示了ASP.NET路由处理URL请求,路由定义(categoryName的默认值为food,action默认为show)和解析结果:
对于MVC应用程序,方法RouteCollectionExtensions.MapRoute的重载版本,如MapRoute(RouteCollection, String, String, Object, Object),允许你指定默认值。 六、 URL模式中处理可变数量片断[Handling a Variable Number of Segments in a URL Pattern]有时候你必须处理包含可变个数的URL片断的URL请求。当你定义一个路由时,你可以指定当一个URL拥有比模式中还要多的片断时,额外的片断会被当作最后一个片断对待。你需要为最后一个参数添加一个星号(*)来用这种方式处理额外的片断。这被称作全匹配(catch-all)参数。包含全匹配参数也将匹配最后参数不带任何值的URL。下例展示一个可以匹配无法确定片断长度的路由模式。 query/{queryname}/{*queryvalues} 下图中演示了ASP.NET路由处理URL请求,路由定义和解析结果。
七、 为路由添加约束[Adding Constraints to Routes]路由模式中除了定义了可匹配URL请求的参数个数,还可以指定这些参数的值需要满足的某些约束。如果一个URL中的参数值不符合一个路由的约束,那么此路由不会处理该请求。你添加的约束条件是为了确保URL参数中包含的值能在你的应用程序中工作。 约束条件是用正则表达式或实现了接口IRouteConstraint的对象来定义。当你将一条路由添加进Routes 集合时,你可以添加包含验证测试的对象RouteValueDictionary约束条件。字典中的键唯一标识符合约束条件的参数。字典中的值既可以是符合正则表达式的字符串,也可以是实现接口IRouteConstraint的对象。 如果你提供一个字符串,路由会将它当作符合正则表达式的值,并调用Regex类的IsMatch()方法检查该参数值是否符合规则。正则表达式总是不区分大小写检查。 如果你提供了一个IRouteConstraint对象,ASP.NET路由调用IRouteConstraint对象的Match()方法来检查参数值是否合法。Match()方法返回布尔值来表明参数值是否合法。 下例中演示如何利用方法MapPageRoute 添加一条路由,并为参数locale和year添加约束。(MVC应用程序中,使用方法MapRoute。) public static void RegisterRoutes(RouteCollection routes) { routes.MapPageRoute("", "Category/{action}/{categoryName}", "~/categoriespage.aspx", true, new RouteValueDictionary {{"categoryName", "food"}, {"action", "show"}}, new RouteValueDictionary {{"locale", "[a-z]{2}-[a-z]{2}"},{"year", @"\d{4}"}} ); } 当路由处理URL请求时,例子中路由的定义和解析后的结果如下表所示:
八、 路由不起作用的情况[Scenarios When Routing Is Not Applied]在某些情况下,ASP.NET路由即使可用也不会处理请求。这节将介绍几种路由不会处理请求的情况。 URL模式匹配一个有效的物理文件[A Physical File is Found that Matches the URL Pattern]默认情况下,路由不会处理请求时,将其映射到Web服务器上一个已存在的物理文件。例如,如果存在一个物理文件Products/Beverages/Coffee.aspx,路由就不会处理请求http://server/application/Products/Beverages/Coffee.aspx。路由即使如下定义{controller}/{action}/{id},也能匹配该请求,它也不会处理该请求。 如果你希望路由能处理所有请求,即使请求指向一个文件,你可以通过设置对象RouteCollection的属性RouteExistingFiles为true来重写默认行为。当你将这个值设置为true则所有与定义路由模式匹配的请求都会被路由处理。 显式禁用路由[Routing Is Explicitly Disabled for a URL Pattern]你也可以指明路由不处理某些URL请求。定义一个路由并指明由类StopRoutingHandler处理该模式,以阻止路由处理某些请求。当一个请求被StopRoutingHandler对象处理时,StopRoutingHandler对象块会为请求添加一些额外的信息。相反,这个请求会被当作一个ASP.NET页面、Web服务或是其他ASP.NET终端处理。你可以使用方法RouteCollection.Ignore(MVC应用程序中RouteCollectionExtensions.IgnoreRoute)来创建使用类 StopRoutingHandler的路由。下面演示如何阻止对WebResource.axd文件的请求。 public static void RegisterRoutes(RouteCollection routes) { routes.Ignore("{resource}.axd/{*pathInfo}"); } URL是如何被路由匹配的[How URLs Are Matched to Routes] 当路由开始处理URL请求时,它为尝试着将请求匹配到一条路由规则上。一条路由规则能否匹配URL请求取决与以下条件:
为了避免不合适的路由处理了请求,在定义路由规则时一定要考虑所有这些条件。集合 Routes中Route对象出现的顺序也应仔细思考。路由集合中从第一项到最后一项依次尝试的路由匹配。当有一个匹配成功,不再对后续路由尝试匹配。通常,添加路由时应先添加最具体的,最后添加最不明确的规则。 例如你添加了如下路由规则:
路由2绝不会处理请求,因为路由1会最先尝试匹配,并且与路由2匹配的请求在它上面也总是可以工作。例如请求http://server/application/products/show/bikes看起来好像和路由2更匹配,但是它会被路由1解析,解析结果如下:
当请求的参数缺少时,默认值就能起作用。然而,它们可能会匹配到并非你所愿的请求。例如,假如添加如下两条路由规则:
路由2将绝无处理请求的机会。路由1希望能按月份匹配,而路由2则希望是按年度。但是,路由1中的默认值会让所有匹配路由2的请求在路由1中也能工作。 你可以在路由中包含常量来避免这种歧义,例如annual/{report}/{year}和monthly/{report}/{year}/{month}。 如果一个URL不能匹配到在RouteTable集合中的任何一个Route对象,ASP.NET路由将不会处理该请求。 九、 从路由创建URL[Creating URLs from Routes]如果你想要创建一个链接到你站点页面的超链接,你可以使用URL模式编程创建符合路由的URL。当你修改了路由模式,URL会自动匹配到新的模式上。 十、 在路由页面访问URL参数[Accessing URL Parameters in a Routed Page]参见:https://msdn.microsoft.com/en-us/library/dd535620.aspx https://msdn.microsoft.com/en-us/library/dd394711.aspx 十一、 配置路由环境[Configuration Settings for Routing]ASP.NET中,要让应用程序支持路由功能,需要添加如下配置: <configuration> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <!-- more --> </modules> </system.webServer> </configuration> 当runAllManagedModulesForAllRequests为true时,如下URLhttp://mysite/myapp/home,即使URL中没有.aspx,.mvc或者其他扩展名,该请求也能到达ASP.NET。 然而,IIS7的更新导致不必添加配置项runAllManagedModulesForAllRequests,因为它本来就支持ASP.NET路由功能。 如果你的站点运行在IIS7且IIS已更新,你就不必设置该配置项为true。事实上,并不推荐设置它,因为它为所有请求增加了不必要的操作。如果设置该配置为true,所有请求,包括.htm,.jpg和其他静态文件都会通过ASP.NET请求通道。 默认runAllManagedModulesForAllRequests为false。如果网站配置文件中没有明确将其设置为true,而你又在未安装SP1的Windows 7,不包含必要更新的IIS7中运行你的网站。 结果就是,你会看到路由不会工作的错误提示。如果路由中存在一些问题,你可以试试下面的方法:
十二、 ASP.NET路由与安全性[ASP.NET Routing and Security]授权规则可应用于单独映射的路由URL或同时映射的路由URL和物理URL。例如,授权规则可以声明所有用户都可以访问以开头Category的URL,但是只有管理员才能访问Categories.aspx页面。如果路由URL模式contoso.com/Category/{controller}/{action} 映射到物理地址contoso.com/Categoriespage.aspx,你只能为路由地址添加授权规则,当用一个路由地址请求过之后,所有用户都被允许可访问Categoriespage.aspx。然而,当使用物理地址请求之后,只有管理才有权限访问。 默认情况下,授权规则应用于路由地址和物理地址。 十三、 ASP.NET Web Form和路由安全性[ASP.NET Web Forms and Route Security]在ASP.NET Web窗体应用程序中,你不应该将站点的安全性全寄托在路由授权规则,因为它们可能留下一些未保护处理的物理地址。 十四、 ASP.NET MVC和路由安全性[ASP.NET MVC and Route Security]你不能使用路由或web.config文件保证MVC应用程序的安全性。唯一能保证MVC应用安全的做法是给所有控制器应用特性 AuthorizeAttribute ,并在登录和注册的方法(action)上应用特性AllowAnonymousAttribute 。 十五、 参考类[Class Reference]
十六、 ASP.NET路由VS URL重写[ASP.NET Routing versus URL Rewriting]ASP.NET路由与URL重写不同。URL重写方式处理到达的请求时,先修改其URL再将请求发送至Web页面。例如,一个应用程序中可能使用URL重写将/Products/Widgets/修改为/Products.aspx?id=4。同时,URL重写的特点是没有基于你的模式创建URL的API。使用URL重写,如果你需要个性URL规则,你不得不手动更新所有相关联的超链接。 使用ASP.NET路由,在处理到达的请求时URL不会发生变化,因为路由功能可能从URL中提取值。当你需要创建一个URL时,给一个方法传入参数值就能为你生成URL。修改URL规则,只需要调整一个地方,你在应用程序中创建的所有链接都会自动使用新规则。
|
请发表评论