2008-09-23 14 views
8

Supongamos que tengo una página que muestra resultados de búsqueda. Busco stackoverflow y devuelve 5000 resultados, 10 por página. Ahora me encuentro haciendo esto cuando la construcción de enlaces de la página:ASP.Net MVC Mantener los parámetros de acción entre las devoluciones de datos

<%=Html.ActionLink("Page 1", "Search", new { query=ViewData["query"], page etc..%> 
<%=Html.ActionLink("Page 2", "Search", new { query=ViewData["query"], page etc..%> 
<%=Html.ActionLink("Page 3", "Search", new { query=ViewData["query"], page etc..%> 
<%=Html.ActionLink("Next", "Search", new { query=ViewData["query"], page etc..%> 

No me gusta esto, tengo que construir mis vínculos con una cuidadosa consideración a lo que fue publicado previamente etc ..

lo que había desea hacer es

<%=Html.BuildActionLinkUsingCurrentActionPostData 
     ("Next", "Search", new { Page = 1}); 

donde el diccionario anónimo anula todo lo establecido actualmente por acción anterior.

Esencialmente me importan los parámetros de acción anteriores, porque quiero reutilizar, suena simple, pero empiezo a agregar opciones de búsqueda avanzada y comienza a complicarse.

Im probablemente perdiendo algo obvio

+1

Este es un problema tan obvio que no puedo creer que el equipo de MVC no haya hecho nada para hacerlo más fácil. –

Respuesta

1

Siempre que se encuentre escribiendo código redundante en sus vistas, write a helper. El ayudante podría copiar explícitamente los parámetros, como lo está haciendo ahora, o podría iterar toda la colección y copiar automáticamente. Si fuera yo, probablemente elegiría el primero. Luego puede llamar a su nuevo ayudante, en lugar de reconstruir los parámetros cada vez que crea un enlace.

1

Soy un poco dudoso en cuanto a lo que en realidad está tratando de hacer aquí. Creo que está intentando automatizar el proceso de creación de una lista de enlaces con solo pequeños cambios entre ellos. Aparentemente en tu caso, el número de identificación de "Página".

Una forma de hacerlo, aunque posiblemente no lo mejor es como tal (Mi código hace uso de una lista básica y artificial del producto y de la ViewPage y PartialViewPage tanto utilizar modelos de tipo firme):

En su ViewPage se añadiría código como este:

<div id="product_list"> 
     <% foreach (TestMVC.Product product in ViewData.Model) 
      { %> 
      <% Html.RenderPartial("ProductEntry", product); %> 
     <% } %> 
</div> 

Su Vista parcial, en mi caso "ProductEntry", sería el siguiente aspecto:

<div class="product"> 
    <div class="product-name"> 
     <%= Html.ActionLink(ViewData.Model.ProductName, "Detail", new { id = ViewData.Model.id })%> 
    </div> 
    <div class="product-desc"> 
     <%= ViewData.Model.ProductDescription %> 
    </div>  
</div> 

todo lo que estoy haciendo en t hat Parcial View está consumiendo el modelo/viewdata que se pasó de la vista primaria por la llamada a Html.RenderPartial

En su vista principal podría modificar un parámetro en su objeto modelo antes de la llamada a Html.RenderPartial para establecer el valor específico que le interesa.

Espero que esto ayude.

12

Tuve un problema similar dentro de un HtmlHelper; Quería generar enlaces que enlazaran con el respaldo de la página actual, con un pequeño ajuste en los parámetros (piense en incrementar el número de página). Entonces, si tuviera URL/Item /? Sort = Name & page = 0, quería poder crear enlaces a la misma página, pero simplemente cambie el parámetro de página, y tenga el parámetro de clasificación automáticamente incluido (es decir,/Item /? ordenar = Nombre & página = 1).

Mi solución era esto (para su uso en un método de extensión HtmlHelper, pero ya que se puede acceder a los mismos datos en casi cualquier lugar en el MVC, puede adaptarla fácilmente a sus usos):

private static RouteValueDictionary CreateRouteToCurrentPage(HtmlHelper html) 
{ 
    RouteValueDictionary routeValues 
     = new RouteValueDictionary(html.ViewContext.RouteData.Values); 

    NameValueCollection queryString 
     = html.ViewContext.HttpContext.Request.QueryString; 

    foreach (string key in queryString.Cast<string>()) 
    { 
     routeValues[key] = queryString[key]; 
    } 

    return routeValues; 
} 

Lo que el método does es tomar el RouteValueDictionary para la solicitud actual y crear una copia de la misma. Luego agrega cada uno de los parámetros de consulta encontrados en la cadena de consulta a esta ruta. Hace esto porque, por algún motivo, la solicitud actual de RouteValueDictionary no los contiene (uno pensaría que sí, pero no es así).

, entonces puede tomar el diccionario resultante, sólo se modifique una parte de ella, por ejemplo:

routeValues["page"] = 2; 

y luego dar ese diccionario a los métodos HtmlHelper fuera de la caja para que generen se una URL/etc.

+0

la única solución real a la pregunta, debería haber sido aceptada. – daniel

+1

Aunque no puedo ver ninguna otra forma de hacerlo, toda esa copia de cobro no se ve muy bonita. –

1

Siguiendo método de ayuda no sólo eso:

public static string EnhancedActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, bool keepQueryStrings) 
    { 
     ViewContext context = helper.ViewContext; 
     IDictionary<string, object> htmlAttributes = null; 
     RouteValueDictionary routeValues = null; 
     string actionLink = string.Empty; 
     if (keepQueryStrings && context.RequestContext.HttpContext.Request.QueryString.Keys.Count > 0) 
     { 
      routeValues = new RouteValueDictionary(context.RouteData.Values); 
      foreach (string key in context.RequestContext.HttpContext.Request.QueryString.Keys) 
      { 
       routeValues[key] = context.RequestContext.HttpContext.Request.QueryString[key]; 
      } 
     }    
     actionLink = helper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes); 
     return actionLink; 
    } 
0

echar un vistazo a esto, es un buen ejemplo: http://nerddinnerbook.s3.amazonaws.com/Part8.htm

+0

Si bien este enlace puede responder a la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página vinculada cambia. – Smamatti

0

Aquí está la extensión del enlace de acción

 

    public static class ActionLinkExtension 
    { 
     public static MvcHtmlString ActionLinkWithQueryString(this HtmlHelper helper, string linkText, string action, string controller, object routeValues) 
     { 
      var context = helper.ViewContext; 

      var currentRouteValues = new RouteValueDictionary(context.RouteData.Values); 
      foreach (string key in context.HttpContext.Request.QueryString.Keys) 
      { 
       currentRouteValues[key] = context.HttpContext.Request.QueryString[key]; 
      } 

      var newRouteValues = new RouteValueDictionary(routeValues); 

      foreach (var route in newRouteValues) 
      { 
       if (!currentRouteValues.ContainsKey(route.Key)) 
       { 
        currentRouteValues.Add(route.Key, route.Value); 
       } 
       else 
       { 
        currentRouteValues[route.Key] = route.Value; 
       } 
      } 

      return helper.ActionLink(linkText, action, controller, currentRouteValues, null); 
     } 

    } 
 
0

No es exactamente una respuesta, pero vale la pena señalar: si desea la funcionalidad de paginación, use el paquete PagedList Nuget (No es necesario volver a inventar la rueda). El siguiente enlace proporciona un buen ejemplo de cómo usarlo: ASP.NET Tutorial

Esto es especialmente útil para usted porque las cadenas de consulta se guardan en la URL al cambiar de una página a otra.

+0

El usuario está preguntando una manera de combinar ordenaciones y paginación que ese tutorial no hace. Muestra una y otra forma de combinarlas para que pueda obtener, por ejemplo, un orden de clasificación en la página 2. Cada vez que selecciona una ordenación o una página, restablece la otra. – Josh

Cuestiones relacionadas