zoukankan      html  css  js  c++  java
  • 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上,处理流程图如下:

      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
    }

      附件:RouteDebug.rar

  • 相关阅读:
    WCF服务编程设计规范
    键盘虚拟键值编码表 使用keybd_Event
    RealTime Executive (REX)使用手册
    SQL Server函数大全(一)
    Windows Mobile常用程序代码(串口、图象、网络、3D、数据库、音频视频等等)
    python写简单爬虫的五种方法 (转)
    配置eclipse+PyDev(转) & 解决Eclipse中文乱码
    HDU 4003 Find Metal Mineral (树形DP)
    HDU 1054 Strategic Game
    HDU 4548 美素数 (线段树)
  • 原文地址:https://www.cnblogs.com/libingql/p/2435687.html
Copyright © 2011-2022 走看看