2010-09-28 38 views
23

tengo una página ASP.NET que tiene una serie de parámetros en la cadena de consulta:Cambiar sola consulta URL valor de cadena

search.aspx?q=123&source=WebSearch 

Esto mostrará la primera página de resultados de búsqueda. Ahora, dentro de la representación de esa página, quiero mostrar un conjunto de enlaces que permitan al usuario saltar a diferentes páginas dentro de los resultados de búsqueda. Puedo hacer esto simplemente agregando &page=1 o &page=2 etc.

Donde se complica es que quiero preservar la cadena de consulta de entrada de la página original para cada parámetro excepto el que estoy tratando de cambiar. Puede haber otros parámetros en la URL utilizada por otros componentes y el valor que estoy tratando de reemplazar puede o no haber definido:

search.aspx?q=123&source=WebSearch&page=1&Theme=Blue 

En este caso para generar un enlace a la página siguiente de resultados, Deseo cambiar page=1 a page=2 sin modificar el resto de la cadena de consulta.

¿Existe alguna forma integrada de hacerlo, o debo hacer todo el análisis/recombinación de cadenas manualmente?

Respuesta

0

Uso del UriBuilder Específicamente la propiedad de consulta link text

creo que hace lo que necesita.

+0

UriBuilder me permite cambiar a cabo todo el componente de consulta de la solicitud de URL, lo que estoy tratando de hacer es cambiar/añadir un parámetro de consulta específica dentro de la URL. – star

5

El uso de este QueryStringBuilder helper class, se puede agarrar la cadena de consulta actual y llamar al método Add cambiar un par clave/valor existente ...

//before: "?id=123&page=1&sessionId=ABC" 
string newQueryString = QueryString.Current.Add("page", "2"); 
//after: "?id=123&page=2&sessionId=ABC" 
+0

Buen recurso. ¡Gracias! – Mark1270287

+0

La nueva versión usa el formato: cadena newQueryString = QueryString.Current.Add ("página", "2"). ToString(); – Mark1270287

51

No se puede modificar el QueryString directamente, ya que es de sólo lectura. Deberá obtener los valores, modificarlos y luego volverlos a unir. Prueba esto:

var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString()); 
nameValues.Set("page", "2"); 
string url = Request.Url.AbsolutePath; 
string updatedQueryString = "?" + nameValues.ToString(); 
Response.Redirect(url + updatedQueryString); 

Los ParseQueryString method devuelve un NameValueCollection (en realidad lo que realmente devuelve un HttpValueCollection que codifica los resultados, as I mention in an answer to another question). Luego puede usar el método Set para actualizar un valor. También puede usar el método Add para agregar uno nuevo o Remove para eliminar un valor. Finalmente, al llamar al ToString() en el nombre NameValueCollection, se devuelven los pares de valores de nombre en un formato name1=value1&name2=value2 querystring listo. Una vez que tenga eso, añádalo a la URL y redirija.

Alternativamente, se puede añadir una nueva clave, o modificar una existente, utilizando el indexador:

nameValues["temp"] = "hello!"; // add "temp" if it didn't exist 
nameValues["temp"] = "hello, world!"; // overwrite "temp" 
nameValues.Remove("temp"); // can't remove via indexer 

Es posible que necesite añadir un using System.Collections.Specialized; para hacer uso de la clase NameValueCollection.

+0

En realidad, puede configurarlo directamente, la reflexión le permite modificar esto. Personalmente, estoy de acuerdo con el uso de un NVC. – annakata

+0

@annakata acaba de leer su respuesta. Enfoque interesante, no es lo primero que se le viene a la mente. –

+0

Hay un problema más con el método ToString. Maneja incorrectamente claves con valores múltiples. En lugar de hacer una lista separada por comas, duplica pares pares clave = valor. Por ejemplo, si ha agregado param de entrada dos veces con los valores value1, value2 obtendrá el parámetro param = value1 y param = value2 en lugar de param = value1, value2. – Stoune

12

Puede hacerlo sin toda la sobrecarga de redirección (que no es insignificante). Mi preferencia personal es trabajar con un NameValueCollection cual una cadena de consulta que realmente es, pero utilizando la reflexión:

// reflect to readonly property 
PropertyInfo isReadOnly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); 

// make collection editable 
isReadOnly.SetValue(this.Request.QueryString, false, null); 

// remove 
this.Request.QueryString.Remove("foo"); 

// modify 
this.Request.QueryString.Set("bar", "123"); 

// make collection readonly again 
isReadOnly.SetValue(this.Request.QueryString, true, null); 
+0

Esta es una solución bastante buena que no estaba seguro de si funcionaría, pero funcionó el truco para mí. Realmente no podía pagar una respuesta. Directa basada en mi arquitectura y podría evitar con este enfoque. ¡Gracias! –

+0

Recibo el error "'PropertyInfo' es un tipo en 'Reflejo' y no se puede usar como expresión." – jbyrd

0

Esto es bastante arbitraria, en .NET Core por lo menos.Y todo se reduce a asp-all-route-data

Consideremos el siguiente ejemplo trivial (tomado del "paginador" modelo de vista que uso en prácticamente todos los proyectos):

public class SomeViewModel 
{ 

    public Dictionary<string, string> NextPageLink(IQueryCollection query) 
    { 
     /* 
     * NOTE: how you derive the "2" is fully up to you 
     */ 
     return ParseQueryCollection(query, "page", "2"); 
    } 

    Dictionary<string, string> ParseQueryCollection(IQueryCollection query, string replacementKey, string replacementValue) 
    { 
     var dict = new Dictionary<string, string>() 
     { 
      { replacementKey, replacementValue } 
     }; 

     foreach (var q in query) 
     { 
      if (!string.Equals(q.Key, replacementKey, StringComparison.OrdinalIgnoreCase)) 
      { 
       dict.Add(q.Key, q.Value); 
      } 
     } 

     return dict; 
    } 
} 

entonces para usar en su opinión, sólo tiene que pasar el método de la colección actual de solicitud de consulta de Context.Request:

<a asp-all-route-data="@Model.NextPageLink(Context.Request.Query)">Next</a> 
Cuestiones relacionadas