zoukankan      html  css  js  c++  java
  • System.Web.Routing 路由功能详解(整理版)

    System.Web.Routing已经作为一个程序集包含在.net3.5sp1中发布了。虽然我们并没有在3.5sp1中发现Asp.net Mvc的踪迹,但是亦以感觉到它离我们不远了。

    System.Web.Routing用于在Asp.netWeb应用程序中进行URLRouting

    所谓UrlRouting就是将一个地址映射为另一个地址,比如我访问/chsword/2008/08/27.html其实是访问了/chsword/article.aspx?y=2008&m=08&d=27这个地址,URLRouting使我们的URL看起来非常漂亮。

    本文将分2部分介绍UrlRouting的使用分别为入门篇与进阶篇。

    文章的前提:

    1.         安装Visual Studio 2008 sp1或其它IDE的等同版本。

    2.         建立一个Asp.net Web ApplicationAsp.net Web应用程序)

    3.         引用System.Web.Routing程序集。

    UrlRouting的实现原理

    如果你不是追求理论的人,仅仅是务实主义,可以直接从准备工作读起。

    为了方便大家理解我绘制了一个UML图,其中通过RouteTableRoutes这个属性可以获取一个RouteCollectionSingleton模式,虽然在其中并没有判断值不存在时才初始化的Singleton的标志性行为,但是它是在Application_Start事件中进行初始化的,并且直到应用程序进程终结,所以是Singleton模式的。

     

    而通过以下方式将Route添加到RouteTable.Routes

    RouteTable.Routes.Add(new Route());

    以上代码仅为表示其流程,这个代码是不能正确执行的,因为Route没有提供无参构造函数。

    Route初始化时则是利用RouteValueDictionary来加入默认值及规则到Route

    另外Route还有一个IRouteHandler的实现对象,IRouteHandler的实现对象提供了一个GetHttpHandler方法来获取用于处理URLIHttpHandler

    这么说还是停留在抽象层次的,下面我们以一些简单例子来带你驭起UrlRouting

    准备工作

    由于须要一个处理UrlIHttpHandler所以我们先定义一个实现了IHttpHandler接口的类。

    就叫它MyPage,由于我们要与IRouteHandler交互,所以除了实现IHttpHandler的方法之外还要声明一个RequestContext类型的属性

    public class MyPage:IHttpHandler {
            
    public RequestContext RequestContext { getprivate set; }
            
    public MyPage(RequestContext context)
            {
                
    this.RequestContext = context;
            }
            
    #region IHttpHandler 成员
            
    public virtual void ProcessRequest(HttpContext context){}
            
    public bool IsReusable {
                
    get { return false; }
            }
            
    #endregion
        }

    这样我们就拥有了一个自己的IHttpHandler

    下面我们实现一个IRouteHandler

    public class MyRouteHandler : IRouteHandler {
            
    #region IRouteHandler 成员
            
    public IHttpHandler GetHttpHandler(RequestContext requestContext) {
                
    return new MyPage(requestContext);
            }
            
    #endregion
        }

    这里实现了IRouteHandlerGetHttpHandler方法,使之返回刚才我们实现的MyPage

    这样我们前期的2个工作就做完了,我们可以来实现UrlRouting了。

    实现第一个UrlRouting

    其实UrlRouting在定义完上两个规则后就很简单了。

    Golbal.asax(没有可以新建一个)的Application_Start事件中写如下代码

    protected void Application_Start(object sender, EventArgs e) {
                RegisterRoutes(RouteTable.Routes);
            }
            
    public static void RegisterRoutes(RouteCollection routes) {
                routes.Add(
    new Route("{page}.aspx",new MyRouteHandler()));
            }

    这样我们就定义了第一个UrlRouting规则就是对xxxx.aspx这类的Url进行Routing

    但是我们仅仅是定义了处理了什么样的Url,却没定义如何处理。

    我们应该在刚刚定义的MyPageProcessRequest方法中定义如何处理。

    我们将ProcessRequest方法实现如下:

    public virtual void ProcessRequest(HttpContext context){
    context.Server.Execute(        RequestContext.RouteData.Values[
    "page"].ToString().Replace("_","/")+".aspx"
                );
    }

     

     

    很显然这里的RequestContext.RouteData.Values["page"]就是取到刚才的规则{page}.aspx中的page的值即,如果我访问index.aspxRequestContext.RouteData.Values["page"]就是index

    我这里的定义是将”_”替换为”/”所以就是将list_index.aspx这样的URL转到list/index.aspx这样的网页上。

    在这些网页里随意写些可以分辨网页的文字。

    则访问list_chsword.aspx时自动Routing到了list/chsword.aspx上了

    总结一下UrlRouting与以下有关:

    1.         Application_Start中定义的规则

    2.         自己实现的IHttpHandler

    这样您对于UrlRouting就算是入门了,下一篇我们将来讲一些进阶设置。

    预计内容:

    • 规则的默认值
    • 正则规则设置
    • 使用技巧

    上面介绍的是最简单的一种定义方式。当然我们可以建立更复杂的规则。其中就包括设定规则的默认值以及设定规则的正则表达式。

    UrlRouting高级应用

    预计效果:

    当我访问/a/b.aspx时就会转到Default.aspx?category=a&action=b在页面上显示
    category:a
    action:b

    亦如果我访问/chsword/xxxx.aspx就会转到Default.aspx?category
    =chsword&action=xxxx就会显示
    category:chsword

    action:xxxx

    如果访问/chsword/就会转到 Default.aspx?category=chsword&action=index就会显示

     category:chsword

    action:index

     首先我建立一个Route

    routes.Add(
                    
    "Default",
                    
    new Route("{category}/{action}.aspx",
                              
    new RouteValueDictionary(
                                  
    new
                                      {
                                          file 
    = "Default",
                                          category 
    = "home",
                                          action 
    = "index"
                                      }), 
    new MyRouteHandler()
                        )
                    );

    当然IHttpHandler的处理方式也要有所改变

    为了方便查看我使用了下方法:

     

        context.Server.Execute(string.Format("/{0}.aspx?category={1}&action={2}",
                  RequestContext.RouteData.Values.ContainsKey(
    "file")
                    
    ? RequestContext.RouteData.Values["file"].ToString()
                    : 
    "default",
                  RequestContext.RouteData.Values.ContainsKey(
    "category")
                    
    ? RequestContext.RouteData.Values["category"].ToString()
                    : 
    "",
                  RequestContext.RouteData.Values.ContainsKey(
    "action")
                    
    ? RequestContext.RouteData.Values["action"].ToString()
                    : 
    "")
                    );

    即/a/b.aspx是映射到Default.aspx?category=a&action=b

    在Default.aspx中写如下代码:

     category:<%=Request.Params["category"%><br />
       action:
    <%=Request.Params["action"%>

    以显示传入的参数。

    如果在IIS中设置Index.aspx时就算输入/a/也会访问到/a/index.aspx,即默认的会按RouteValueDictionary中设置的值自动补全

    UrlRouting使用正则表达式规则

    UrlRouting在定义的时候也可以按正则的规则来进行定义。

                routes.Add(
                    
    "zz",
                    
    new Route("{category}/{action}.chs",
                        
    new RouteValueDictionary(
                            
    new {
                                file 
    = "Default",
                                category 
    = "home",
                                action 
    = "1"
                            }),
                            
    new RouteValueDictionary(
                            
    new {
                                action 
    = "[\\d]+"
                            }),
                        
    new MyRouteHandler()
                        )
                );

    以上代码规定了action只能是数字则访问/a/1.chs可以正常访问。

    而访问/a/b.chs则会显示未找到资源。

    当然这是里可以使用更高级的正则表达式。

    UrlRouting的技巧

    排除UrlRouting的方法:

    System.Web.Routing默认提供了一个IRouteHandlerStopRoutingHandler Class,经过它处理的URL不会被做任何处理

    通常使用方法如下:

    routes.Add(new Route("{resource}.axd/{*pathInfo}", new StopRoutingHandler()));

    RouteHandler工厂:

    其实IRouteHandler可以实现一个RouteHandler的简单工厂。

        public class RouteHandlerFactory : IRouteHandler
        {
            
    string Name { getset; }
            
    public RouteHandlerFactory(string name){this.Name = name;}
            
    #region IRouteHandler 成员
            
    public IHttpHandler GetHttpHandler(RequestContext requestContext) {
                
    if (this.Name == "mypage")
                    
    return new MyPage(requestContext);
                
    if(this.Name="mypage1")
                    
    return new MyPage1(requestContext);
            }
            
    #endregion
        }

     规定HTTP verbs,这里要使用System.Web.Routing中的HttpMethodConstraint

    void Application_Start(object sender, EventArgs e) {
        RegisterRoutes(RouteTable.Routes);
    }
    public static void RegisterRoutes(RouteCollection routes){
        
    string[] allowedMethods = { "GET""POST" };
        HttpMethodConstraint methodConstraints 
    = new HttpMethodConstraint(allowedMethods);
        Route reportRoute 
    = new Route("{locale}/{year}"new ReportRouteHandler());
        reportRoute.Constraints 
    = new RouteValueDictionary { { "httpMethod", methodConstraints } };
        routes.Add(reportRoute);
    }

    认识 ASP.NET 3.5 MVC 路由 在WebForm项目中使用路由


     

    路由程序集System.Web.Routing位于.NET框架3.5的SP1版本中,是与ASP.NET3.5 MVC分离的,所以在传统的Web Form项目中也可以使用路由。

    ASP.NET 路由使您可以处理未映射到 Web 应用程序中物理文件的 URL 请求。默认情况下,在动态数据或 MVC 框架的一个 ASP.NET 应用程序中启用 ASP.NET 路由,而不在 ASP.NET 网站项目中启用路由。

    因此,若要在 ASP.NET 网站中使用路由,必须采取措施来启用。

    要实现在WebForm中使用路由,首先需要创建实现IRouteHandler接口的WebFormRouteHandler类,然后在全局应用程序类中配置路由的映射就可以了。

    WebFormRouteHandler代码如下:

    using System.Web;
    using System.Web.Compilation;
    using System.Web.Routing;
    using System.Web.UI;
    namespace MVCWebApplication1
    {
        public class WebFormRouteHanlder : IRouteHandler
        {
            public string VirtualPath { get; private set; }
            public WebFormRouteHanlder(string virtualPah)
            {
                VirtualPath = virtualPah;
            }
            public IHttpHandler GetHttpHandler(RequestContext requestContext)
            {
                var page = BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(Page)) as IHttpHandler;
                return page;
            }
        }
    }
    在Global.asax中配置路由:
    using System;
    using System.Web.Routing;
    namespace MVCWebApplication1
    {
        public class Global : System.Web.HttpApplication
        {
            protected void Application_Start(object sender, EventArgs e)
            {
                RegisterRoutes(RouteTable.Routes);
            }
            public static void RegisterRoutes(RouteCollection routes)
            {
                routes.Add("Named", new Route("foo/bar", new WebFormRouteHanlder("~/forms/blech.aspx")));
                routes.Add("Number", new Route("one/two/three", new WebFormRouteHanlder("~/forms/haha.aspx")));
            }
        }
    }

    还需要在Web.config中配置System.Web.Routing的引用!

          <httpModules>
            <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
          </httpModules>

    运行,访问http://localhost:5598/foo/bar 。OK~~~~

  • 相关阅读:
    程序员面试中有几大法则
    实现立方体旋转
    为什么技术与产品沟通起来总是那么痛苦
    移动互联网下半场的面试真经,让你进入 BAT 不再是梦
    Javascript+H5实现打小地鼠游戏
    Python多进程应用
    Python数据分析笔记:聚类算法之K均值
    给新手程序员的16个工作必备小妙招,省下时间去LOL吧!
    MySQL数据库开发常见问题及优化
    java中的四种引用类型
  • 原文地址:https://www.cnblogs.com/GeneralXU/p/1639041.html
Copyright © 2011-2022 走看看