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的生成。例子或許欠佳,但是比較好理解。源碼.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM