好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

mvc3之自定义类实现路由配置和URL的生成

mvc3之自定义类实现路由配置和URL的生成

mvc3之自定义类实现路由配置和URL的生成

在mvc中路由的配置,直接关系着我们的请求访问的控制器和方法;url对seo有着重要作用,全靠mvc内部定义的配置路由和生成url的方法在有的时间是不够的,本文就来了解一下自定义配置路由和url的生成。

一、RouteBase类简介

在新建一个mvc项目后,打开global文件,可以看到路由的注册是使用一个RouteCollection类型的参数来实现的。按F12转到定义会发现,其继承了Collection<RouteBase>,除了一些MapRoute等一些方法之外还有一个Add方法,其签名为:

         public   void  Add( string  name, RouteBase item);

实际上就是一个标记路由的名字,还有一个是RouteBase类,按F12,其对应的有两个方法:

 //  当在派生类中重写时,会返回有关请求的路由信息。 
 public   abstract   RouteData GetRouteData(HttpContextBase httpContext);

  //  当在派生类中重写时,会检查路由是否与指定值匹配,如果匹配,则生成一个 URL,然后检索有关该路由的信息 
 public   abstract  VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);

第一个方法:通过处理请求信息httpContext,来指定通过哪个控制器和方法处理请求的;第二个方法用来指定请求页的连接生成的URL.下面就通过一个实例来说明以上两个方法的使用。

二、使用RouteBase的方法 2.1需求说明

为了让url更加一目了然,在列表分页时,我们通过使用如下URL: http://www.***.com/ 分类/List/Page/n,意思就是某个分类的第n页列表。与此同时,我们对应的上一页,下一页生成对应的URL分别为 http://www.***.com/ 分类/List/Page/n-1, http://www.***.com/ 分类/List/Page/n+1。下面以产品分类列表分页为例,即 http://localhost:***/Product/List/page/n 。当然该需求应该有更好的解决方案,在此仅为了说明RouteBase的使用。为了演示,我们先新建一个MVC项目,在controllers文件夹添加一个ProductController,并简单添加一个类表方法:

 public  ActionResult List( int  page =  1  )
        {
            ViewBag.count  =  page;
            ViewBag.content = "  第  " +page+ "  页  "  ;
              return   View();
        } 

并添加对应的视图,

 @{
    ViewBag.Title  =  "  List  "  ;
}
 <h2>产品列表</h2>
<a href= "  @Url.Action(  " Product "  ,   " List "  , new { page =   " page "  , id = Convert.ToInt32(ViewBag.count) - 1 })  " >上一页</a>
<a href= "  @Url.Action(  " Product "  ,  " List "  ,new {page=  " page "  ,id= ViewBag.count})  " > @ViewBag.content</a>
<a href= "  @Url.Action(  " Product "  ,   " List "  , new { page =   " page "  , id = Convert.ToInt32(ViewBag.count) + 1 })  " >下一页</a>

然后添加一个文件夹Infranstructure,并新建一个类MyHelper,然后让其继承RouteBase类,如图:

2.2GetRouteData的使用

为了配置路由,我们不使用MapRoute方法,可以把global文件里面的默认的MapRoute去掉,我们使用上面的GetRouteData方法,我们通过httpcontext来指定控制器里面的方法以到达处理请求的目的。代码如下:

 public   class   MyHelper : RouteBase
    {
          public   override   RouteData GetRouteData(HttpContextBase httpContext)
        {
              //  指定处理请求的路由对象为MvcRouteHandler对象 
             var  data =  new  RouteData( this ,  new   MvcRouteHandler());
              //  接受请求的url,并对其指定controller和action以及action的参数 
             string  strUrl =  httpContext.Request.RawUrl;
              string [] arry = strUrl.Split( '  /  '  );
              if  (arry.Length >  4  )
            {
                data.Values.Add(  "  controller  " ,  "  Product  "  );
                data.Values.Add(  "  action  " ,  "  List  "  );
                data.Values.Add(arry[  3 ], arry[ 4  ]);
                  return   data;
            }
              /*  如果不符合要求的url,返回null,以便使用其他路由匹配,进而指定
            controller和action以及action的参数  */ 
             return   null  ;
        }
          public   override   VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        {
            //我们暂且返回一个null 
 return   null  ;
       } 
    } 

因为开始的时间,我们去掉了MapRoute,现在我们要使用Add方法,所以在global文件中添加

routes.Add( new  MyHelper());

现在运行程序,并在地址栏输入 http://localhost:3519/Product/List/Page/1 ,效果图如下:

此时的请求已经通过我们的自定义路由生效,但是我们发现,上一页和下一页的连接不是我们想要的,如果想达到我们的要求,那么我们就需要使用GetVirtualPath方法,对该请求页的连接生成指定的URL。

2.3 GetVirtualPath的使用

废话不多说,还是把代码贴出来,部分说明见注释:

         ///   <summary> 
         ///   为指定请求页生成特定的url的样子
          ///   </summary> 
         ///   <param name="requestContext">  请求页  </param> 
         ///   <param name="values">  请求页中的Html.Action等辅助类  </param> 
         ///   <returns></returns> 
         public   override   VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        {
              //  先判断请求是否符合要求——请求的action为List,page不能为空。 
             if  (requestContext.RouteData.Values[ "  action  " ].ToString()== "  List  " &&
                ! string .IsNullOrEmpty(requestContext.RouteData.Values[ "  page  "  ].ToString()))
            {
                  //  定义一个Url字符串 
                 string  strUrl =  string  .Empty;
                  //  如果values中有四个值,做下面的操作 
                 if  (values.Count ==  4  )
                {
                      if  (Convert.ToInt32(values[ "  id  " ]) >=  1  )
                    {
                        strUrl  = values[ "  controller  " ].ToString() +  "  /  "  + values[ "  action  " ].ToString() +  "  /  "  + values[ "  page  " ].ToString() +  "  /  "  + values[ "  id  "  ].ToString();
                    }
                      else  
                    {
                        strUrl  = values[ "  controller  " ].ToString() +  "  /  "  + values[ "  action  " ].ToString() +  "  /  "  + values[ "  page  " ].ToString() +  "  /1#  "  ;
                    }
                      return   new  VirtualPathData( this  , strUrl);
                }
            }
              return   null  ;
        } 

现在运行 http://localhost:3519/Product/List/Page/1 页面,已经是我们想要的结果了。

注意:上面的两个方法判断的时间一定要精确的判断,否则可能指定到错误的控制器和方法上以及错误的url。再者,当不符合指定要求时要返回到null,以便使用其他的路由配置。

三、总结

本文主要通过一个分页的实例来说明自定义路由和URL的生成。例子或许欠佳,但是比较好理解。 源码 .

 

 

分类:  MVC3

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于mvc3之自定义类实现路由配置和URL的生成的详细内容...

  阅读:64次