有時候在 View 需要取得 RouteValue 之後新產生新的網址,尤其是在分頁的時候,常會需要產生新的分頁連結,如果頁面跟參數很多,每次新增一個參數就要重新調整 View ,也沒辦法方便共用分頁的樣版,因此希望可以更方便的產生網址並且也可以支援新增額外的 RouteValue。
前言
有時候在 View 需要取得 RouteValue 之後新產生新的網址,尤其是在分頁的時候,常會需要產生新的分頁連結,如果頁面跟參數很多,每次新增一個參數就要重新調整 View ,也沒辦法方便共用分頁的樣版,因此希望可以更方便的產生網址並且也可以支援新增額外的 RouteValue。方式是從 ViewContext 取得目前頁面的 RouteValue 加上傳入希望額外新增的 RiuteValue 重新組合出 RouteValueDictionary 給 Url Helper 來重新產生新的網址。
實做
底下是我從這邊看到的討論,改成 ASP.NET Core 版再加上去除針對 AJAX 額外產生的參數所改寫的擴充方法如下:
/// <summary>
/// 取得可額外新增 RouteValue 的 RouteValueDictionary
/// </summary>
/// <param name="addtionalRouteValues">額外的 RouteValue</param>
public static RouteValueDictionary GetCombinedRouteValues(this ViewContext viewContext, object addtionalRouteValues)
{
RouteValueDictionary combinedRouteValues = new RouteValueDictionary(viewContext.RouteData.Values);
var queryString = viewContext.HttpContext.Request.Query;
foreach (string key in queryString.Keys.Where(key => key != null && key != "__RequestVerificationToken" && key != "X-Requested-With" && key != "_"))
combinedRouteValues[key] = queryString[key];
if (addtionalRouteValues != null)
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(addtionalRouteValues))
combinedRouteValues[descriptor.Name] = descriptor.GetValue(addtionalRouteValues);
}
return combinedRouteValues;
}
使用範例
以下針對我在使用分頁套件 X.PagedList.Mvc.Core 時候針對分頁撰寫的共用程式碼,因為我是透過 AJAX Get 來取得分頁的內容,透過這樣方式來取得下的查詢條件的參數,加上目前分頁的參數來產生對應的分頁網址。
@using X.PagedList.Mvc.Core
@using X.PagedList.Mvc.Core.Common
@using X.PagedList.Web.Common
@model IPagedList
@Html.PagedListPager(
Model,
page => Url.Action(ViewContext.RouteData.Values["action"].ToString(), ViewContext.GetCombinedRouteValues(new { Page = page })),
PagedListRenderOptions
.EnableUnobtrusiveAjaxReplacing(
new PagedListRenderOptions()
{
UlElementClasses = new[] { "pagination" },
LiElementClasses = new[] { "page-item" },
PageClasses = new[] { "page-link" },
LinkToPreviousPageFormat = "«",
LinkToNextPageFormat = "»",
DisplayLinkToFirstPage = PagedListDisplayMode.IfNeeded,
DisplayLinkToLastPage = PagedListDisplayMode.IfNeeded,
DisplayLinkToPreviousPage = PagedListDisplayMode.Always,
DisplayLinkToNextPage = PagedListDisplayMode.Always,
MaximumPageNumbersToDisplay = 14
},
new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "Target", OnSuccess = "Success" })
)
結論
本文主要是在使用分頁套件的時候,為了解決分頁 View 的共用,又不想在每一個分頁的頁面去取得參數一一加入,透過此方式可以更方便共用分頁樣式又可以正確取得查詢資料傳入的參數,主要是針對 Get 從 QueryString 取得參數,後續可以針對 Post 在做更進一步的調整。