2017-02-03 11 views
2

現在、ASP.NET Core MVCのページングリストを作成しています。ASP.NET MVC - アクションリンクのクエリ文字列を保存します。

次の作成中に、私は苦労:

私はUrlHelper拡張メソッドを作成したい:その拡張メソッド内 Url.PageLink(int型のページ、int型のpageSize)

を、私はどのリンクを返すようにしたいですコントローラ、アクション、クエリ文字列のすべての現在の値を再利用します。さらに、クエリー文字列のpage、pageSize値も追加/更新する必要があります。

質問: ここからは、現在のコントローラとアクションをUrlHelperオブジェクトで取得できますか? クエリ文字列を再構築する最良の方法は何ですか? ここではurl.ActionContext.HttpContext.Request.QueryStringを見ることができますが、実際に手動で再構築する必要はありますか?または、AddQueryStringValue(int key、object value)のようなものが存在しますか?

ありがとうございます! サイモン

+0

URLHelperはどこから消費されますか?必要な情報を含むViewModelを考案する必要があります。なぜあなたはQuerystringを使用していますか? – Wheels73

+0

このメソッドをどのような種類のビューでも動作させたいので、クエリ文字列が必要です。私は特定のviewmodelに行きたいとは思わない。私はちょうど拡張メソッドを作成したい 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); 
    } 
} 

そして、ちょうどpagedlist値に対して個別の入力モデル「PagedListInputModel」を作成した私は、私はすべての場所でそれを再利用できるようにすることができます...この道をpageおよびpageSizeプロパティが、必要なすべてのビューモデルに正しい名前で含まれていることを確認する必要はありません。

フィードバックは歓迎します。

0

Simonの答えの改善: @Url.Current(new {page=42, id=5, foo=bar}) これは、クエリ文字列を保持し、提供された値を更新/追加します。

​​
0

質問にはAsp.Net Coreが必要です。私はMVC 5でshturmの答えを使用しようとしていて、動作させることができませんでした。私は彼の同じコンセプトをとり、MVC 5で動作するように変更しました。誰でもこのverisonが必要な場合は、ここに投稿します。私はアクションとコントローラを変更する機能も追加しました。

/// <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); 
    } 
関連する問題