ASP.NET MVC系列:UrlRouting

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上,处理流程图如下:

ASP.NET MVC系列:UrlRouting

  URLRewrite为将URL映射到具体的文件资源上,处理流程图如下:

ASP.NET MVC系列:UrlRouting

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
}

  附件:RouteDebug.rar

你可能感兴趣的:(asp.net)