2009-02-27 18 views
39

Quiero tener diferente clasificación y filtrado aplicadas en mi opinión que pensé que voy a estar pasando de clasificación y filtrado params través de la cadena de consulta:¿Cómo accedo a los parámetros de cadena de consulta en asp.net mvc?

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

Esta sencilla construcción me permite ordenar. Ver regresa con esto en la cadena de consulta:

?SortBy=Name 

Ahora quiero añadir filtrado y quiero que mi cadena de consulta para terminar con

?SortBy=Name&Filter=Something 

¿Cómo puedo añadir otro parámetro a la lista de los ya existentes unos en ActionLink? Por ejemplo:

user requests /Index/ 

View ha

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

y

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

Enlaces: El primero de ellos se parece a /Index/?SortBy=Name y el segundo es /Index/?FilterBy=Name

quiero cuando el usuario enlace de clasificación presionado a Después de aplicar algunos filtros, no se pierde el filtrado, por lo que necesito una forma de combinar mis parámetros. Supongo que debería haber una manera de no analizar cadena de consulta, pero obtener una colección de parámetros de algún objeto MVC.

+0

¿Qué tal una sintaxis de afeitar actualizada a la pregunta? – MrBoJangles

+1

ya está ... solo me tomó 4 años .. (-: –

Respuesta

29

Hasta ahora, la mejor manera que he descubierto es crear una copia de ViewContext.RouteData.Values e insertar los valores de QueryString en ella. y luego modificarlo antes de cada uso de ActionLink. intentando averiguar cómo usar .Union() en lugar de modificar un diccionario todo el tiempo.

<% 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

Otra [pregunta] (http://stackoverflow.com/questions/391023/make-namevaluecollection-accessible-to-linq-query/396504) indica que esta es la mejor manera cuando se usa '@ Html.ActionLink'. Configuré para' Name '. – Grastveit

+8

¿Alguna mejor forma de hacerlo usando ASP.NET MVC 3 o 4? –

+0

@LenielMacaferi, Ver modelos –

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

para preservar la cadena de consulta puede:

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

O si usted tiene más parámetros, se podría construir el enlace de forma manual mediante el uso teniendo en cuenta Request.QueryString.

4

Uso ActionLinkCombined en lugar de 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

Mi solución es similar a la de qwerty1000. Creé un método de extensión, ActionQueryLink, que tiene los mismos parámetros básicos que el estándar ActionLink. Recorre Request.QueryString y agrega los parámetros encontrados en el diccionario RouteValues que aún no están presentes (para que podamos sobrescribir la cadena de consulta original si es necesario).

para preservar la cadena existente pero no agregue ninguna clave del uso sería:

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

Para preservar la cadena existente y añadir nuevas claves al usuario sería:

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

El código siguiente es para los dos usos, pero debería ser bastante fácil agregar otras sobrecargas para que coincidan con las otras extensiones ActionLink según sea necesario.

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" }) 

O

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

cadena de consulta sería como:

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

tendría class="cssClass"

+0

vea esta línea' new { @id = 5, @name = "textName", @abc = "abc"} 'por qué usas @ sign muchas veces. @ sign se usa para palabra clave reservada. – Thomas

Cuestiones relacionadas