zoukankan      html  css  js  c++  java
  • 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类,如图:

    image

    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,效果图如下:

    image

    此时的请求已经通过我们的自定义路由生效,但是我们发现,上一页和下一页的连接不是我们想要的,如果想达到我们的要求,那么我们就需要使用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页面,已经是我们想要的结果了。

    image

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

    三、总结

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

     
     
    分类: MVC3
  • 相关阅读:
    js 实现加入收藏/加入首页功能
    js 获取网页宽/高度
    js 飞机大战
    js 实现分享功能
    前端开发的工具,库和资源总结
    网站更新后客户端缓存问题
    js 实现图片无限横向滚动效果
    js 实现 文字打印效果
    js 构造函数创建钟表
    Css3 实现关键帧动画
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3021602.html
Copyright © 2011-2022 走看看