2009-04-22 7 views
48

Estoy buscando la forma más sencilla de convertir una cadena de consulta de una solicitud HTTP GET en un diccionario, y viceversa.La mejor manera de convertir la cadena de consulta al diccionario en C#

Me imagino que es más fácil realizar varias manipulaciones en la consulta una vez que está en forma de diccionario, pero parece que tengo un montón de código solo para hacer la conversión. ¿Alguna forma recomendada?

Respuesta

60

HttpUtility.ParseQueryString() análisis sintáctico de la cadena de consulta en un objeto NameValueCollection, la conversión de este último a un IDictionary<string, string> se trata de un simple foreach. Esto, sin embargo, puede ser innecesario ya que NameValueCollection tiene un indexador, por lo que se comporta de forma muy parecida a un diccionario.

+0

y viceversa: http://stackoverflow.com/questions/829080/how-to-build-a-query-string-for-a-url-in-c – Rudi

+12

Request.QueryString ya es una NameValueCollection, La respuesta @ H70 es la más fácil de poner en un diccionario 'var parameters = Reque st.QueryString.Keys.Cast () .ToDictionary (k => k, v => Request.QueryString [v]); ' –

9

sólo tenía que hacer esto para una solución compatible mono

Regex.Matches(queryString, "([^?=&]+)(=([^&]*))?").Cast<Match>().ToDictionary(x => x.Groups[1].Value, x => x.Groups[3].Value) 
+0

También funciona para Windows Phone 8 (el' HttpUtility.ParseQueryString' tampoco existe) – nemesisfixx

+1

. . . y espero que tus llaves ('Grupos [1]') sean únicas. –

+0

@BinaryWorrier y si no son simples .GroupBy (x => x.Groups [1] .Value) .ToDictionary (g => g.Key, g => g.Primer(). Grupos [3]. Valor); funcionaría (con pérdida de datos evidente) – drake7707

5

me gusta la brevedad de Jon Canning's answer, pero en aras de la variedad, aquí es otra alternativa a su respuesta, que también funcionaría para entornos restringidos como Windows Phone 8, que carecen de la HttpUtility.ParseQueryString() utilidad:

public static Dictionary<string, string> ParseQueryString(String query) 
    { 
     Dictionary<String, String> queryDict = new Dictionary<string, string>(); 
     foreach (String token in query.TrimStart(new char[] { '?' }).Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries)) 
     { 
      string[] parts = token.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); 
      if (parts.Length == 2) 
       queryDict[parts[0].Trim()] = HttpUtility.UrlDecode(parts[1]).Trim(); 
      else 
       queryDict[parts[0].Trim()] = ""; 
     } 
     return queryDict; 
    } 

en realidad, una mejora útil a la respuesta de Canning que se ocupan de los valores de codificación URL de decodificación (como en la solución anterior) es:

public static Dictionary<string, string> ParseQueryString2(String query) 
    { 
     return Regex.Matches(query, "([^?=&]+)(=([^&]*))?").Cast<Match>().ToDictionary(x => x.Groups[1].Value, x => HttpUtility.UrlDecode(x.Groups[3].Value)); 
    } 
22

Así es como normalmente lo hago

Dictionary<string, string> parameters = HttpContext.Current.Request.QueryString.Keys.Cast<string>() 
       .ToDictionary(k => k, v => HttpContext.Current.Request.QueryString[v]); 
+0

¡Fácil y directo!Se merece un +1 :-) – Matt

+0

para una respuesta elegante – mzonerz

2

Un forro sin HttpUtility

var dictionary = query.Replace("?", "").Split('&').ToDictionary(x => x.Split('=')[0], x => x.Split('=')[1]); 
+0

Su código hará excepción cuando endwith ("&") – Adrian

+0

bien, no he pensado en ese caso de uso. Puede agregar '.Where (x =>! String.IsNullOrEmpty (x))' antes del '.ToDictionary' para evitar esa excepción – vicentedealencar

+0

Puede simplemente agregar un parámetro StringSplitOptions.RemoveEmptyEntries a .Split ('&'): .Split (new [] {'&'}, StringSplitOptions.RemoveEmptyEntries) –

4

Sin embargo, otra manera de hacerlo:

NameValueCollection nvcData = HttpUtility.ParseQueryString(queryString); 
Dictionary<string, string> dictData = new Dictionary<string, string>(nvcData.Count); 
foreach (string key in nvcData.AllKeys) 
{ 
    dictData.Add(key, nvcData.Get(key)); 
} 
4

Igual que Sean, pero con Linq (y una función que puede copiar y pegar):

public static Dictionary<string, string> ParseQueryString(string queryString) 
{ 
    var nvc = HttpUtility.ParseQueryString(queryString); 
    return nvc.AllKeys.ToDictionary(k => k, k => nvc[k]); 
} 

Además, la pregunta que cómo conseguir de nuevo en una cadena de consulta:

public static string CreateQueryString(Dictionary<string, string> parameters) 
{ 
    return string.Join("&", parameters.Select(kvp => 
     string.Format("{0}={1}", kvp.Key, HttpUtility.UrlEncode(kvp.Value)))); 
} 
0

más sencilla:

Dictionary<string, string> parameters = new Dictionary<string, string>(); 

for (int i = 0; i < context.Request.QueryString.Count; i++) 
{ 
    parameters.Add(context.Request.QueryString.GetKey(i), context.Request.QueryString[i]); 
} 
No
+0

Agregue una descripción a su segmento de código, solo el bloque de código no ayudará mucho. – Billa

Cuestiones relacionadas