2009-02-09 4 views
51

Quiero eliminar la cadena de consulta de "Idioma" de mi url. Cómo puedo hacer esto ? (Con Asp.net 3.5, C#)¿Cómo puedo eliminar un elemento de querystring en asp.net usando C#?

Default.aspx?Agent=10&Language=2 

Quiero eliminar "Language = 2", pero el lenguaje sería el primer nombre, segundo o último. así que voy a tener este

Default.aspx?Agent=20 
+0

Por favor, explique más de lo que su objetivo son. No creo que esté buscando una forma de editar el campo de dirección de los usuarios, ¿verdad? –

Respuesta

10

Respondí similar question hace un tiempo. Básicamente, la mejor manera sería usar la clase HttpValueCollection, que es la propiedad QueryString, desafortunadamente es interna en .NET framework. Puede usar Reflector para tomarlo (y colocarlo en su clase Utils). De esta forma, podría manipular la cadena de consulta como NameValueCollection, pero con todos los problemas de codificación/decodificación de url que se preocupan por usted.

HttpValueCollection extiende NameValueCollection, y tiene un constructor que toma una cadena de consulta codificada (símbolos de unión y signos de interrogación incluidas), y se anula un método ToString() para reconstruir después la cadena de consulta de la colección subyacente.

+0

He leído tu publicación y me parece genial. Gracias por su respuesta, lo intentaré y volveré –

+0

No estoy seguro si este fue el único método disponible en 2009, pero hay otra manera sin reflexión en otra respuesta para esta pregunta: http://stackoverflow.com/a/7530346/169034 –

0

lo que probablemente va a querer usar una expresión regular para encontrar el parámetro que desea eliminar de la cadena de consulta, a continuación, quitarlo y redirigir el navegador en el mismo archivo con su nueva cadena de consulta .

0

Sí, no hay clases integradas en .NET para editar cadenas de consulta. Tendrás que usar Regex u otro método para alterar la cadena.

1

No deja en claro si está tratando de modificar la Querystring en el objeto Request. Dado que esa propiedad es de solo lectura, supongo que asumiremos que solo quieres jugar con la cadena.

... En cuyo caso, es limítrofe trivial.

  • agarrar la cadena de consulta de la solicitud
  • .split() en '&'
  • poner de nuevo juntos en una nueva cadena, mientras aspira a lanzar y cualquier cosa que empieza con "lenguaje"
+0

De acuerdo, si no quiere meterse con RegEx, obtenga la consulta de Rquest.Url.Query, divida en & y vuelva a generarla sin la cadena de consulta del idioma.Puede usar un UriBuilder, pero no toma pares de nombre y valor para construir querystrings :( –

+0

Hace mucho tiempo construí mi propia clase LinkUri que puede dividir URL, construirlas a partir de clave/valor y .tostring() en URLs de nuevo. Básicamente, hace lo que le gustaría que hiciera UriBuilder. Tomó una mañana para armarla hace 4 años, y la uso todos los días. –

+0

Estoy en eso, odio jugar con cuerdas, oh Dios :) Pero con de esta manera me siento más cómodo –

1

obtener la colección cadena de consulta, lo revisará en un (name=value pair) de cadena, con exclusión de la persona que desea eliminar, y el nombre de newQueryString

Luego llame al Response.Redirect(known_path?newqueryString);

+0

esto fue lo primero que he intentado, gracias. –

113

Si se trata de HttpRequest.QueryString, puede copiar la colección en una colección editable y salirse con la suya.

NameValueCollection filtered = new NameValueCollection(request.QueryString); 
filtered.Remove("Language"); 
+2

esto es simple y elegante - ojalá pudiera chocar un par de veces – Doug

+5

Gracias por eso Doug. Estoy un poco desconcertado por la respuesta aceptada. Parece que la pregunta está causando que ocurra otra navegación para sacar el parámetro no deseado de la cadena de consulta. – xcud

+0

System.Collections.Specialized.NameValueCollection filtered = new System.Collections.Specialized.NameValueCollection (Request.QueryString); –

36

Por último,

hmemcpy respuesta fue totalmente para mí y gracias a otros amigos que respondieron.

me agarra el HttpValueCollection usando Reflector y escribió el siguiente código

 var hebe = new HttpValueCollection(); 
     hebe.Add(HttpUtility.ParseQueryString(Request.Url.Query)); 

     if (!string.IsNullOrEmpty(hebe["Language"])) 
      hebe.Remove("Language"); 

     Response.Redirect(Request.Url.AbsolutePath + "?" + hebe); 
+2

Esta es la respuesta correcta aquí. El .NET Framework tiene el método de cadena de consulta de análisis de utilidad HTTP para este propósito. No es necesario duplicar el código de un reflector o usar expresiones regulares. La razón por la que la colección de cadenas de consulta en el contexto de solicitud es de solo lectura es porque modificarla haría que el contexto fuera preciso con respecto a la solicitud original. El método de cadena de consulta de análisis proporciona simplemente una nueva colección no vinculada al contexto de solicitud que no es de solo lectura. Por favor, podrían marcar esto como la respuesta correcta aquí, gracias. – danielrbradley

+0

Prefiero hacer esto sin la redirección si es posible, que está usando Reflection (vea la respuesta de @annakata) – LocalPCGuy

+0

Parece que ParseQueryString devuelve una lectura/escritura HttpValueCollection, por lo que no es necesario crear su propia versión de la misma. Ver la respuesta de Paulius Zaliaduonis a continuación. –

26

Mi preferencia personal aquí es reescribir la consulta o trabajar con un NameValueCollection en un punto más bajo, pero hay momentos en que la lógica de negocio hace que ni de esos muy útiles y algunas veces la reflexión realmente es lo que necesitas. En esas circunstancias, simplemente puede apagar la bandera de solo lectura por un momento así:

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

cosas geniales. ¿Esto no es peligroso en absoluto? ¿Cuál es el alcance de this.Request.QueryString en este contexto? – Skuli

+0

@Skuli: estás modificando algo que no está destinado a modificación, y lo estás haciendo cambiando una bandera de estado. Existe el riesgo de que pueda hacer algo destructivo si se olvida de "cerrar" el cambio de reflejo, pero es bastante bajo y requeriría que un desarrollador no se dé cuenta de lo que está haciendo el código. La solicitud aquí tiene un alcance a través de IHttpHandler, por lo que cualquier System.Web.Page anterior puede hacer esto. – annakata

+1

Estoy usando esto en un caso en el que tengo un UserControl que no puedo modificar que utiliza un parámetro de cadena de consulta, y la única forma de cambiar la forma en que se comporta UserControl es cambiar la cadena de consulta antes de procesarla (también puedo No cambio la URL entrante real, tengo que modificarla durante el ciclo de carga). Muy útil, y funciona muy bien. – LocalPCGuy

44

Aquí hay una manera simple. Reflector no es necesario

public static string GetQueryStringWithOutParameter(string parameter) 
    { 
     var nameValueCollection = System.Web.HttpUtility.ParseQueryString(HttpContext.Current.Request.QueryString.ToString()); 
     nameValueCollection.Remove(parameter); 
     string url = HttpContext.Current.Request.Path + "?" + nameValueCollection; 

     return url; 
    } 

Aquí se requiere QueryString.ToString() porque Request.QueryString colección es de sólo lectura.

+9

Esta es la respuesta correcta – Kyle

+1

La solución más simple y elegante. – Blairg23

+0

Una nota aquí es que la línea 'string url = HttpContext.Current.Request.Path +"? " + nameValueCollection; 'codificará' nameValueCollection', por lo que a veces los espacios se convierten en "+", lo que puede no ser la sintaxis correcta para la solicitud que está a punto de realizar. En mi caso, no fue así. Tuve que asignar las claves y los valores en un bucle for en su lugar. – Blairg23

0

Si usted tiene ya la cadena de consulta como una cadena, también se puede utilizar la manipulación de cadenas simples:

int pos = queryString.ToLower().IndexOf("parameter="); 
if (pos >= 0) 
{ 
    int pos_end = queryString.IndexOf("&", pos); 
    if (pos_end >= 0) // there are additional parameters after this one 
     queryString = queryString.Substring(0, pos) + queryString.Substring(pos_end + 1); 
    else 
     if (pos == 0) // this one is the only parameter 
      queryString = ""; 
     else  // this one is the last parameter 
      queryString=queryString.Substring(0, pos - 1); 
} 
3

probar este ...

PropertyInfo isreadonly =typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);  

isreadonly.SetValue(this.Request.QueryString, false, null); 
this.Request.QueryString.Remove("foo"); 
-1

así tengo una solución simple, pero hay un poco de javascript involucrado.

asumiendo la cadena de consulta es "ok = 1"

string url = Request.Url.AbsoluteUri.Replace("&ok=1", ""); 
    url = Request.Url.AbsoluteUri.Replace("?ok=1", ""); 
    Response.Write("<script>window.location = '"+url+"';</script>"); 
+2

esto probablemente sería la peor forma de hacerlo –

+0

por favor explique cuál es el problema, insted escriba su opinión sin explicación –

+1

El valor "1" en su ejemplo probablemente será dinámico, lo que significa que la cadena "& ok = 1 "o"? Ok = 1 "tendrá que crearse manualmente y luego reemplazarse. Tu respuesta no es la manera más limpia de hacer lo que se pide. Además, la pregunta que se hizo no mencionaba la implementación de javascript. –

1
  1. Reúna a su cadena de consulta mediante el uso de HttpContext.Request.QueryString. Se predetermina como un tipo NameValueCollection.
  2. Colóquelo como una cadena y use System.Web.HttpUtility.ParseQueryString() para analizar la cadena de consulta (que devuelve NameValueCollection nuevamente).
  3. Puede utilizar la función Remove() para eliminar el parámetro específico (usando la tecla para hacer referencia a ese parámetro para eliminar).
  4. Utilice los parámetros de consulta para una cadena y use string.Join() para formatear la cadena de consulta como algo legible por su URL como parámetros de consulta válidos.

Vea a continuación un ejemplo de trabajo, donde param_to_remove es el parámetro que desea eliminar.

Digamos que sus parámetros de consulta son param1=1&param_to_remove=stuff&param2=2. Ejecutar las siguientes líneas:

var queryParams = System.Web.HttpUtility.ParseQueryString(HttpContext.Request.QueryString.ToString()); 
queryParams.Remove("param_to_remove"); 
string queryString = string.Join("&", queryParams.Cast<string>().Select(e => e + "=" + queryParams[e])); 

Ahora su cadena de consulta debe ser param1=1&param2=2.

+0

Esto es casi idéntico a la respuesta de PauliusZaliaduonis. La tercera línea de tu código es un poco más complicada. –

+0

Sin embargo, agregué un poco de explicación en caso de que las personas no entendieran el proceso. – Blairg23

0
string queryString = "Default.aspx?Agent=10&Language=2"; //Request.QueryString.ToString(); 
string parameterToRemove="Language"; //parameter which we want to remove 
string regex=string.Format("(&{0}=[^&\s]+|{0}=[^&\s]+&?)",parameterToRemove); 
string finalQS = Regex.Replace(queryString, regex, ""); 

https://regexr.com/3i9vj

Cuestiones relacionadas