2009-02-27 12 views
39

chcę mieć różny sortowanie i filtrowanie stosowane na moim zdaniem Pomyślałem, że będę przechodzącej sortowanie i filtrowanie params poprzez ciąg kwerendy:Jak uzyskać dostęp do parametrów ciągu zapytania w asp.net mvc?

@Html.ActionLink("Name", "Index", new { SortBy= "Name"}) 

Ta prosta konstrukcja pozwala mi uporządkować. Zobacz wraca z tym w ciągu zapytania:

?SortBy=Name 

Teraz chcę dodać filtrowanie i chcę mój ciąg kwerendy skończyć z

?SortBy=Name&Filter=Something 

Jak mogę dodać kolejny parametr do listy już istniejących te w ActionLink? na przykład:

user requests /Index/ 

pogląd

@Html.ActionLink("Name", "Index", new { SortBy= "Name"}) 

i

@Html.ActionLink("Name", "Index", new { FilterBy= "Name"}) 

Linki: Pierwszy wygląda jak /Index/?SortBy=Name a drugi /Index/?FilterBy=Name

chcę kiedy użytkownik wciśnięty link sortujący po zastosowaniu niektórych filtrów - filtrowanie nie jest tracone, więc potrzebuję sposobu na połączenie moich parametrów. Zgaduję, że powinien istnieć sposób, aby nie parsować ciąg zapytania, ale uzyskać kolekcję parametrów z jakiegoś obiektu MVC.

+0

Co powiesz na aktualizację brzytwy na pytanie? – MrBoJangles

+1

proszę .. tylko zajęło mi to 4 lata .. (-: –

Odpowiedz

29

Do tej pory najlepszym sposobem, jaki wymyśliłem, jest utworzenie kopii ViewContext.RouteData.Values i wstawienie do niej wartości QueryString. , a następnie zmodyfikuj go przed każdym użyciem ActionLink. nadal próbuje dowiedzieć się, jak używać .Union() zamiast stale modyfikować słownik.

<% RouteValueDictionary tRVD = new RouteValueDictionary(ViewContext.RouteData.Values); %> 

<% foreach (string key in Request.QueryString.Keys) 
    { 
     tRVD[key]=Request.QueryString[key].ToString(); 
    } %> 

<%tRVD["SortBy"] = "Name"; %> 
       <%= Html.ActionLink("Name", "Index", tRVD)%> 
+0

Kolejne [pytanie] (http://stackoverflow.com/questions/391023/make-namevaluecollection-accessible-to-linq-query/396504) wskazuje, że jest to najlepszy sposób przy użyciu '@ Html.ActionLink'. Ustawiłem na' Name '. – Grastveit

+8

Każdy lepszy sposób robienia tego przy użyciu ASP.NET MVC 3 lub 4? –

+0

@LenielMacaferi, Zobacz modele –

8
<%= Html.ActionLink("Name", "Index", new { SortBy= "Name", Filter="Something"}) %> 

Aby zachować ciągu kwerendy można:

<%= Html.ActionLink("Name", "Index", 
    String.IsNullOrEmpty(Request.QueryString["SortBy"]) ? 
     new { Filter = "Something" } : 
     new { SortBy=Request.QueryString["SortBy"], Filter="Something"}) %> 

Lub jeśli masz więcej parametrów, można ręcznie zbudować link za pomocą biorąc Request.QueryString pod uwagę.

4

Zastosowanie ActionLinkCombined zamiast ActionLink

 public static string ActionLinkCombined(this HtmlHelper htmlHelper, string linkText, string actionName, 
              object routeValues) 
    { 
     var dictionary = new RouteValueDictionary(); 
     foreach (var pair in htmlHelper.ViewContext.Controller.ValueProvider) 
      dictionary[pair.Key] = pair.Value.AttemptedValue; 
     if (routeValues != null) 
     { 
      foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(routeValues)) 
      { 
       object o = descriptor.GetValue(routeValues); 
       dictionary[descriptor.Name] = o; 
      } 
     } 
     return htmlHelper.ActionLink(linkText, actionName, dictionary); 
    } 
12

Moje rozwiązanie jest podobne do qwerty1000 tych. Stworzyłem metodę rozszerzenia, ActionQueryLink, która przyjmuje te same podstawowe parametry, co standard ActionLink. Pętla poprzez Request.QueryString i dodaje wszelkie parametry znalezione w słowniku RouteValues, które nie są już obecne (abyśmy mogli w razie potrzeby zastąpić oryginalny ciąg zapytania).

Aby zachować istniejący ciąg ale nie dodawać żadnych kluczy użycie byłoby:

<%= Html.ActionQueryLink("Click Me!","SomeAction") %> 

Aby zachować istniejący ciąg i dodać nowe klucze użytkownik będzie:

<%= Html.ActionQueryLink("Click Me!","SomeAction", new{Param1="value1", Param2="value2"} %> 

Poniższy kod jest dla dwóch zastosowań, ale w miarę potrzeby powinno być całkiem łatwo dodać inne przeciążenia, aby pasowały do ​​innych rozszerzeń ActionLink.

public static string ActionQueryLink(this HtmlHelper htmlHelper, 
     string linkText, string action) 
    { 
     return ActionQueryLink(htmlHelper, linkText, action, null); 
    } 

    public static string ActionQueryLink(this HtmlHelper htmlHelper, 
     string linkText, string action, object routeValues) 
    { 
     var queryString = 
      htmlHelper.ViewContext.HttpContext.Request.QueryString; 

     var newRoute = routeValues == null 
      ? htmlHelper.ViewContext.RouteData.Values 
      : new RouteValueDictionary(routeValues); 

     foreach (string key in queryString.Keys) 
     { 
      if (!newRoute.ContainsKey(key)) 
       newRoute.Add(key, queryString[key]); 
     } 
     return HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, 
      htmlHelper.RouteCollection, linkText, null /* routeName */, 
      action, null, newRoute, null); 
    } 
2

MVC4

@Html.ActionLink("link text","action",new { @id = 5, @name = "textName", @abc = "abc" }) 

lub

@Html.ActionLink("link text", "action", "controller", new { @id = 5, @name = "textName", @abc = "abc" }, new { @class = "cssClass" }) 

querystring będzie jak:

yourDomainRout/action/5?name=textName&abc=abc 

będzie miał class="cssClass"

+0

zobacz ten wiersz' nowy { @id = 5, @name = "textName", @abc = "abc"} "dlaczego używasz znaku @ wiele razy. Znak @ jest zarezerwowany dla słowa kluczowego. – Thomas

Powiązane problemy