2017-02-03 59 views
2

我目前正在爲ASP.NET Core MVC編寫我自己的分頁列表。ASP.NET MVC - 創建操作鏈接保留查詢字符串

我掙扎在創建以下內容:

我想創建一個UrlHelper擴展方法: Url.PageLink(INT頁,詮釋的pageSize)

在這一擴展方法我想返回一個鏈接,重用控制器,動作,查詢字符串的所有當前值,此外,它還應該在查詢字符串中添加/更新頁面,pageSize值。

問題: 從哪裏獲得UrlHelper對象中的當前控制器和動作? 什麼是重建查詢字符串的最佳方法? 我可以在這裏看到它url.ActionContext.HttpContext.Request.QueryString ...但我真的必須手動重建它嗎?或者像AddQueryStringValue(int鍵,對象值)存在嗎?

非常感謝! 西蒙

+0

你打算從哪裏消費你的URLHelper?您需要設計一個包含您所需信息的ViewModel。你爲什麼使用Querystring? – Wheels73

+0

我需要查詢字符串,因爲我想讓這種方法適用於任何類型的視圖。我不想用特定的視圖模型去。我只想創建一個擴展方法 public static string PageLink(this IUrlHelper url,int page,int pageSize) – Simon

+0

我明白了。那麼QS本身只是一個關鍵值對的集合..你可以把它作爲你的分機的一個參數。方法? – Wheels73

回答

1

現在已經做了這樣的:

public static class UrlHelperExtensions 
{ 
    public static string Page(this IUrlHelper url, int page, int pageSize) 
    { 
     //Reuse existing route values 
     RouteValueDictionary resultRouteValues = new RouteValueDictionary(url.ActionContext.RouteData.Values); 

     //Add existing values from query string 
     foreach (var queryValue in url.ActionContext.HttpContext.Request.Query) 
     { 
      if(resultRouteValues.ContainsKey(queryValue.Key)) 
       continue; 

      resultRouteValues.Add(queryValue.Key, queryValue.Value); 
     } 

     //Set or add values for PagedList input model 
     resultRouteValues[nameof(PagedListInputModel.Page)] = page; 
     resultRouteValues[nameof(PagedListInputModel.PageSize)] = pageSize; 

     return url.RouteUrl(resultRouteValues); 
    } 
} 

而且創建了一個單獨的輸入模式「PagedListInputModel」爲只是pagedlist值......這樣我可以保證,我可以在任何地方重用並且不必確保頁面和pageSize屬性包含在具有正確名稱的所有需要​​的視圖模型中。

歡迎任何反饋。

0

Simon的改進回答: 它可以被稱爲@Url.Current(new {page=42, id=5, foo=bar}) 它將保留查詢字符串和更新/添加提供的值。

​​
0

該問題要求Asp.Net Core。我試圖在MVC 5上使用shturm的答案,但無法使其正常工作。我採用了相同的概念,並將其改爲與MVC 5一起工作。如果有人需要此版本,我將在此處發佈它。我還添加了更改操作和控制器的功能。

/// <summary> 
    /// Get URL with substituted values while preserving query string. 
    /// </summary> 
    /// <param name="helper">The url helper object we are extending.</param> 
    /// <param name="action">The action we want to direct to.</param> 
    /// <param name="controller">The controller we want to direct to.</param> 
    /// <param name="substitutes">Query string parameters or route data paremers. E.g. new { action="Index", sort = "asc"}</param> 
    /// <returns>The route string.</returns> 
    public static String ActionWithOriginalQueryString(this UrlHelper helper, String action, String controller, object substitutes) 
    {    
     RouteValueDictionary routeData = new RouteValueDictionary(helper.RequestContext.RouteData.Values); 
     NameValueCollection queryString = helper.RequestContext.HttpContext.Request.QueryString; 

     //add query string parameters to the route data 
     foreach (var param in queryString.AllKeys) 
     { 
      if (!string.IsNullOrEmpty(queryString[param])) 
      { 
       //rd[param.Key] = qs[param.Value]; // does not assign the values! 
       routeData.Add(param, queryString[param]); 
      } 
     } 

     // override parameters we're changing in the route data 
     //The unmatched parameters will be added as query string. 
     foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(substitutes.GetType())) 
     { 
      var value = property.GetValue(substitutes); 
      if (string.IsNullOrEmpty(value?.ToString())) 
      { 
       routeData.Remove(property.Name); 
      } 
      else 
      { 
       routeData[property.Name] = value; 
      } 
     } 

     //Set the controller and the action. 
     routeData["controller"] = controller; 
     routeData["action"] = action; 

     //Return the route. 
     return helper.RouteUrl(routeData); 
    }