1. URLRouting简介
URL(Uniform Resource Locator),统一资源定位器,是用于完整描述Internet上的网页或其他资源地址的一种标识方法。
URL一般可以由6部分组成,格式如下:
protocol :// hostname [:port] [/path] [?parameters] [#fragment]
URL各部分说明:
protocol 协议:可以是HTTP(超文本传输协议)、FTP(文件传输协议)和HTTPS(安全超文本传输协议)。
hostname 主机名:指在互联网中存放资源的服务器DNS主机名或IP地址。
port 端口号:该选项是一个小于66536的正整数,是各服务器或协议约定的通信端口。
path 路径:用来表示一个Web站点中的目录或文件资源的地址。
parameters 参数列表:参数形式为以=隔开的键/值对,多个参数之间用&连接。
fragment 信息片段:用于直接定位到页面中的某个锚点标记。
2. URLRouting与URLRewrite区别
URLRouting是一组从URL到请求处理程序间的映射规则,将URL映射到能够处理业务需求的Action上。URLRouting是一个独立的类库System.Web.Routing.dll。
URLRouting为将URL映射到Controller的Action上,处理流程图如下:
URLRewrite为将URL映射到具体的文件资源上,处理流程图如下:
3. ASP.NET MVC中使用及自定义URLRouting规则
在Web.config文件中与Routing有关的的节点:sytem.web.httpModules,system.web.httpHandlers,system.webserver.modules,system.webserver.handlers。
ASP.NET MVC应用程序第一次启动时,将调用Global.asax中Application_Start()方法。每个ASP.NET MVC应用程序至少需要定义一个URLRouting来指明应用程序如何处理请求,复杂的应用程序可以包含多个URLRouting。
3.1 App_Start/RouteConfig.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace Libing.Portal.Web { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } }
Global.asax
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace Libing.Portal.Web { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); } } }
3.2 Route类
RouteCollection对象以静态属性的方式声明在RouteTable的属性Routes中,RouteCollection对象存储的是Route类的实例。一个完整的Route类实例需要有URL、默认值、约束、数据密钥及路由处理程序等属性。
public RouteValueDictionary Constraints { get; set; } public RouteValueDictionary DataTokens { get; set; } public RouteValueDictionary Defaults { get; set; } public IRouteHandler RouteHandler { get; set; } public string Url { get; set; }
3.3 Route类属性
name:
路由名称,必须是唯一不能重复。
url:
在Route类中,属性URL是一个字符串,用于描述请求中URL的格式。该字符串可能不完全是一个实际的URL,可以带一些{}标记的占位符,使用占位符可以从URL中提取数据。如:
"{controller}/{action}/{id}"
{controller}参数的值用于实例化一个处理请求的控制类对象,{action}参数的值用于指明处理当前请求将调用控制器中的方法。
defaults:
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
constraints:
new { controller = @"^\w+", action = @"^\w+", id = @"\d+" }
namespaces:
Route.DataTokens属性,获取或设置传递到路由处理程序但未用于确定该路由是否匹配 URL 模式的自定义值。
3.4 自定义URLRouting规则
分页:
routes.MapRoute(
"Page",
"{controller}/List/Page/{page}",
new { controller = "Home", action = "List", page = UrlParameter.Optional },
new { page = @"\d*" }
);
public string List(int? page)
{
return page == null ? "1" : page.ToString();
}
本地化多语言Routing:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // 本地化 routes.MapRoute( name: "Localization", url: "{lang}/{controller}/{action}/{id}", defaults: new { lang = "zh-CN", controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { lang = "^[a-zA-Z]{2}(-[a-zA-Z]{2})?$" } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }
分页Routing:
routes.MapRoute( name: "PagedList", url: "{controller}/Page/{page}", defaults: new { controller = "Product", action = "Index" }, constraints: new { page = @"\d+" } );
Blog根据日期Routing:
routes.MapRoute( name: "blog", url: "blog/{user}/{year}/{month}/{day}", //defaults: new { controller = "Blog", action = "Index", day = 1 }, defaults: new RouteValueDictionary{ {"controller", "Blog"}, {"action", "Index"}, {"day", 1} }, constraints: new { year = @"\d{4}", month = @"\d{1,2}", day = @"\d{1,2}" } );
Reports根据年月Routing:
routes.MapRoute( name: "Reports", url: "Reports/{year}/{month}", defaults: new { controller = "Reports", action = "Index" }, constraints: new { year = @"\d{4}", month = @"\d{1,2}" } );
3.5 创建Routing约束
使用正则表达式来指定路由约束:
routes.MapRoute( name: "Product", url: "Product/{ProductID}", defaults: new { controller = "Product", action = "Details" }, constraints: new { ProductID = @"\d+" } );
3.6 自定义Routing约束
通过实现IRouteConstraint接口来实现自定义路由。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Routing; namespace Libing.Portal.Web.Models.Constraints { public class LocalhostConstraint : IRouteConstraint { public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { return httpContext.Request.IsLocal; } } }
routes.MapRoute( name: "Admin", url: "Admin/{action}", defaults: new { controller = "Admin" }, constraints: new { isLocal = new LocalhostConstraint() } );
自定义浏览器访问Routing约束:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Routing; namespace Libing.Portal.Web.Models.Constraints { public class UserAgentConstraint:IRouteConstraint { private string _userAgent; public UserAgentConstraint(string userAgent) { _userAgent = userAgent; } public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { return httpContext.Request.UserAgent != null && httpContext.Request.UserAgent.Contains(_userAgent); } } }
routes.MapRoute( name: "Chrome", url: "{*catchall}", defaults: new { controller = "Home", action = "Index" }, constraints: new { customConstraint = new UserAgentConstraint("Chrome") } );
自定义用户个人网址Routing:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Routing; using Libing.Portal.Web.Models; namespace Libing.Portal.Web.Models.Constraints { public class UserConstraint : IRouteConstraint { public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { using (PortalContext context = new PortalContext()) { string userRouteValue = values["user"].ToString(); var user = (from u in context.Users where u.UserName == userRouteValue select u).FirstOrDefault(); return user != null; } } } }
routes.MapRoute( name: "User", url: "{user}/{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { isValidUser = new UserConstraint() } );
4. 使用RouteDebugger调试URLRouting
RouteDebugger为一个独立的类库,RouteDebug.dll,可以从网上下载到,使用方法如下:
1>. 添加对RouteDebug引用;
2>. Global.ascx修改
using RouteDebug;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes); // 添加RouteDebug
}
一、认识Global.asax.cs
- public class MvcApplication : System.Web.HttpApplication
- {
- protected void Application_Start()
- {
- //注册 ASP.NET MVC 应用程序中的所有区域
- AreaRegistration.RegisterAllAreas();
- //注册 全局的Filters
- FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
- //注册 路由规则
- RouteConfig.RegisterRoutes(RouteTable.Routes);
- //注册 打包绑定(js,css等)
- BundleConfig.RegisterBundles(BundleTable.Bundles);
- }
- }
- public class RouteConfig
- {
- public static void RegisterRoutes(RouteCollection routes)
- {
- routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
- routes.MapRoute(
- name: "Default",
- url: "{controller}/{action}/{id}",
- defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
- );
- }
- }
![](https://www.lanhusoft.com/attached/image/20150417/20150417151123_5950.gif)
三、ASP.NET MVC默认的命名约定
1、Controller命名约定
2、View命名约定
四、ASP.NET MVC的URL规则说明
![](https://www.lanhusoft.com/attached/image/20150417/20150417151207_5012.gif)
- routes.MapRoute(
- name: "Default",
- url: "{controller}/{action}/{id}",
- defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
- );
URL
| URL段 |
http://mysite.com/Admin/Index
|
controller = Admin
action = Index
|
http://mysite.com/Index/Admin
|
controller = Index
action = Admin
|
http://mysite.com/Apples/Oranges
|
controller = Apples
action = Oranges
|
http://mysite.com/Admin
|
无匹配-段的数量不够
|
http://mysite.com/Admin/Index/Soccer
| 无匹配-段的数量超了 |
五、mvc创建一个简单的Route规则
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("MyRoute", "{controller}/{action}");
- }
- public static void RegisterRoutes(RouteCollection routes) {
- Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler());
- routes.Add("MyRoute", myRoute);
- }
六、mvc路由的默认值的设定
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" });
- }
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("MyRoute", "{controller}/{action}",
- new { controller = "Home", action = "Index" });
- }
Url段的数量
|
实例
|
Route映射
|
0
|
mydomain.com
|
controller = Home
action = Index
|
1
|
mydomain.com/Customer
|
controller = Customer
action = Index
|
2
|
mydomain.com/Customer/List
|
controller = Customer
action = List
|
3
|
mydomain.com/Customer/List/All
|
无匹配—Url段过多
|
七、mvc使用静态URL段
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("MyRoute", "{controller}/{action}",
- new { controller = "Home", action = "Index" });
- routes.MapRoute("", "Public/{controller}/{action}",
- new { controller = "Home", action = "Index" });
- }
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("", "X{controller}/{action}");
- routes.MapRoute("MyRoute", "{controller}/{action}",
- new { controller = "Home", action = "Index" });
- routes.MapRoute("", "Public/{controller}/{action}",
- new { controller = "Home", action = "Index" });
- }
八、mvc的路由中自定义参数变量
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
- new { controller = "Home", action = "Index", id = "1" });
- }
- public ViewResult CustomVariable() {
- ViewBag.CustomVariable = RouteData.Values["id"];
- return View();
- }
九、mvc定义可选URL段、可选参数
1、注册路由时定义可选URL段
2、通过Action参数来定义可选参数
十、mvc使用*来定义变长数量的URL段
Url段的数量
|
实例
|
Route映射
|
0
|
mydomain.com
|
controller = Home
action = Index
|
1
|
mydomain.com/Customer
|
controller = Customer
action = Index
|
2
|
mydomain.com/Customer/List
|
controller = Customer
action = List
|
3
|
mydomain.com/Customer/List/All
|
controller = Customer
action = List
id = All
|
4
|
mydomain.com/Customer/List/All/Delete
|
controller = Customer
action = List
id = All
catchall = Delete
|
5
|
mydomain.com/Customer/List/All/Delete/Perm
|
controller = Customer
action = List
id = All
catchall = Delete /Perm
|
十一、mvc使用命名空间来为路由的Controller类定优先级
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("Default",
- "{controller}/{action}/{id}",
- new { controller = "Home", action = "Index", id = UrlParameter.Optional },
- new string[] { "WebApplication1.Controllers" }
- );
- }
十二、mvc定义路由规则的约束
1、用正则表达式限制asp.net mvc路由规则
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
- new { controller = "Home", action = "Index", id = UrlParameter.Optional },
- new { controller = "^H.*"},
- new[] { "URLsAndRoutes.Controllers"});
- }
2、把asp.net mvc路由规则限制到到具体的值
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
- new { controller = "Home", action = "Index", id = UrlParameter.Optional },
- new { controller = "^H.*", action = "^Index$|^About$"},
- new[] { "URLsAndRoutes.Controllers"});
- }
3、把asp.net mvc路由规则限制到到提交请求方式(POST、GET)
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
- new { controller = "Home", action = "Index", id = UrlParameter.Optional },
- new { controller = "^H.*", action = "Index|About",
- httpMethod = new HttpMethodConstraint("GET") },
- new[] { "URLsAndRoutes.Controllers" });
- }
4、使用接口IRouteConstraint自定义一个asp.net mvc路由约束
- using System.Web;
- using System.Web.Routing;
- namespace URLsAndRoutes.Infrastructure {
- public class UserAgentConstraint : IRouteConstraint {
- private string requiredUserAgent;
- public UserAgentConstraint(string agentParam) {
- requiredUserAgent = agentParam;
- }
- public bool Match(HttpContextBase httpContext, Route route, string parameterName,
- RouteValueDictionary values, RouteDirection routeDirection) {
- return httpContext.Request.UserAgent != null &&
- httpContext.Request.UserAgent.Contains(requiredUserAgent);
- }
- }
- }
- public static void RegisterRoutes(RouteCollection routes) {
- routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
- new { controller = "Home", action = "Index", id = UrlParameter.Optional },
- new {
- controller = "^H.*", action = "Index|About",
- httpMethod = new HttpMethodConstraint("GET", "POST"),
- customConstraint = new UserAgentConstraint("IE")
- },
- new[] { "URLsAndRoutes.Controllers" });
- }
十三、mvc将URL路由到磁盘文件
- public static void RegisterRoutes(RouteCollection routes) {
- routes.RouteExistingFiles = true;
- routes.MapRoute("DiskFile", "Content/StaticContent.html",
- new {
- controller = "Account", action = "LogOn",
- },
- new {
- customConstraint = new UserAgentConstraint("IE")
- });
- routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
- new { controller = "Home", action = "Index", id = UrlParameter.Optional },
- new {
- controller = "^H.*", action = "Index|About",
- httpMethod = new HttpMethodConstraint("GET", "POST"),
- customConstraint = new UserAgentConstraint("IE")
- },
- new[] { "URLsAndRoutes.Controllers" });
- }
十四、mvc跳过、绕开路由系统设定
- public static void RegisterRoutes(RouteCollection routes) {
- routes.RouteExistingFiles = true;
- routes.MapRoute("DiskFile", "Content1/StaticContent.html",
- new {
- controller = "Account", action = "LogOn",
- },
- new {
- customConstraint = new UserAgentConstraint("IE")
- });
- routes.IgnoreRoute("Content/*{filename}");
- routes.MapRoute("", "{controller}/{action}");
- }