2011-08-06 15 views
28

Tengo el siguiente código:Obtener todos los valores de una NameValueCollection a una cadena

string Keys = string.Join(",",FormValues.AllKeys); 

yo estaba tratando de jugar con el get:

string Values = string.Join(",", FormValues.AllKeys.GetValue()); 

Pero por supuesto que no funciona .

Necesito algo similar para obtener todos los valores, pero no encuentro el código apropiado para hacer lo mismo.

P.S: No quiero utilizar un bucle foreach ya que eso supera el propósito de la primera línea de código.

Respuesta

34
var col = new NameValueCollection() { { "a", "b" }, { "1", "2" } }; // collection initializer 

var values = col.Cast<string>().Select(e => col[e]); // b, 2 

var str = String.Join(",", values); // "b,2" 

También puede crear un método de extensión:

public static string Join(this NameValueCollection collection, Func<string,string> selector, string separator) 
{ 
    return String.Join(separator, collection.Cast<string>().Select(e => selector(e))); 
} 

Uso:

var s = c.Join(e => String.Format("\"{0}\"", c[e]), ","); 

también se puede convertir fácilmente NameValueCollection a más práctico Dictionary<string,string> manera:

public static IDictionary<string,string> ToDictionary(this NameValueCollection col) 
{ 
    return col.AllKeys.ToDictionary(x => x, x => col[x]); 
} 

Da:

var d = c.ToDictionary(); 

Como ya he encontrado usando Reflector, NameValueCollection.AllKeys realiza internamente un bucle para reunir todos te llaves, así que parece que c.Cast<string>() es más preferible.

+0

solo una pequeña adición, ¿se pueden agregar citas a cada valor? – Dementic

+0

@Dementic: Claro. Simplemente use 'c.Select (e => String.Format (" \ "{0} \" ", c [e]));' – abatishchev

+0

gracias, esta fue una muy buena respuesta! – Dementic

7
string values = 
    string.Join(",", FormValues.AllKeys.SelectMany(key => FormValues.GetValues(key))); 

Editar: Las otras respuestas pueden o no ser lo que quieres. Parecen más simples, pero los resultados pueden no ser lo que está buscando en todas las circunstancias, pero de nuevo, podrían ser (su kilometraje puede variar).

Tenga en cuenta que NameValueCollection no es un mapeo 1: 1 como un diccionario. Puede agregar varios valores para la misma clave, por lo que una función como .GetValues(key) devuelve una matriz, no una sola cadena.

Si usted tiene una colección en la que han añadido

collection.Add("Alpha", "1"); 
collection.Add("Alpha", "2"); 
collection.Add("Beta", "3"); 

Recuperando collection["Alpha"] rendimientos "1,2". Recuperando collection.GetValues("Alpha") cede { "1", "2" }. Ahora, sucede que estás usando una coma para unir tus valores en una sola cadena, por lo que esta disparidad está oculta. Sin embargo, si se unían en otro valor, como un signo de exclamación, los resultados de las otras respuestas serían

"1,2!3" 

Y el código aquí serían

"1!2!3" 

Usar el fragmento que demuestra la comportamiento que prefieres

21
string values = string.Join(",", collection.AllKeys.Select(key => collection[key])); 
+1

Así es como lo hice. La solución más simple, pero tal vez no la más legible en todas las instancias. Esto también se puede lograr usando un ciclo foreach y simplemente concatenando los pares clave: valor. – Blairg23

-1
List<string> values = new List<string>(); 
values.AddRange(all.AllKeys.SelectMany(all.GetValues).Where(getValues => getValues != null)); 
string Values = string.Join(",", values.ToArray()); 

Puede intentar algo como lo anterior.

7

A continuación, se crea una cadena a partir de la lista de parámetros de la URL.

string.Join(", ", 
      Request.QueryString 
        .AllKeys 
        .Select(key => key + ": " + Request.QueryString[key]) 
     .ToArray()) 

es decir

page.aspx?id=75&page=3&size=7&user=mamaci 

habría

id: 75, page: 3, size: 7, user: mamaci 
0

En los casos en que haya analizado la cadena de consulta con System.Web.HttpUtility.ParseQueryString (...), puedes usar ToString() y no tiene que reinventar la rueda.

Aunque el resultado es NameValueCollection, el tipo subyacente es HttpValueCollection que tiene la anulación de ToString() necesaria para volver a generar una cadena de consulta.

0

estoy usando Azure DocumentDB como mi mecanismo de registro, por lo tanto, escribir un objeto dinámico, pero se obtiene lo esencial ...

public class LogErrorAttribute : HandleErrorAttribute 
{ 
    public override void OnException(ExceptionContext filterContext) 
    { 
     int responseCode = new int(); 

     // Has the exception been handled. Also, are custom errors enabled 
     if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) 
      return; 

     // Check if custom exception, if so get response code 
     if (filterContext.Exception is CustomException) 
      responseCode = (int)((CustomException)filterContext.Exception).Code; 

     // Log exception 
     string id = Logging.Write(LogType.Error, new 
     { 
      ResponseCode = responseCode, 
      Exception = new 
      { 
       Message = filterContext.Exception.Message, 
       Data = filterContext.Exception.Data, 
       Source = filterContext.Exception.Source, 
       StackTrace = filterContext.Exception.StackTrace, 
       InnerException = filterContext.Exception.InnerException != null ? new 
       { 
        Message = filterContext.Exception.InnerException.Message, 
        Data = filterContext.Exception.InnerException.Data, 
        Source = filterContext.Exception.InnerException.Source, 
        StackTrace = filterContext.Exception.InnerException.StackTrace 
       } : null 
      }, 
      Context = filterContext.Controller != null ? new 
      { 
       RouteData = filterContext.Controller.ControllerContext.RouteData, 
       QueryString = filterContext.Controller.ControllerContext.HttpContext.Request.Url.Query, 
       FormParams = filterContext.Controller.ControllerContext.HttpContext.Request.Form != null ? string.Join(";#", filterContext.Controller.ControllerContext.HttpContext.Request.Form.AllKeys.Select(key => key + ":" + filterContext.Controller.ControllerContext.HttpContext.Request.Form[key])) : string.Empty, 
       Model = (filterContext.Controller is Controller) ? ((Controller)filterContext.Controller).ModelState : null, 
       ViewBag = filterContext.Controller.ViewBag, 
       ViewData = filterContext.Controller.ViewData 
      } : null, 
      ActionResult = filterContext.Result != null ? filterContext.Result : null, 
      Referrer = filterContext.HttpContext.Request.UrlReferrer != null ? filterContext.HttpContext.Request.UrlReferrer : null 
     }).Result; 

     // Mark exception as handled and return 
     filterContext.ExceptionHandled = true; 

     // Test for Ajax call 
     if (IsAjax(filterContext)) 
     { 
      // Construct appropriate Json response 
      filterContext.Result = new JsonResult() 
      { 
       Data = new 
       { 
        code = responseCode, 
        id = id, 
        message = filterContext.Exception.Message 
       }, 
       JsonRequestBehavior = JsonRequestBehavior.AllowGet 
      }; 

     } 
     else 
     { 
      var result = new ViewResult(); 
      result.ViewName = "_CustomError"; 
      result.ViewBag.CorrelationId = id; 
      filterContext.Result = result; 
     } 
    } 

    /// <summary> 
    /// Determine if the request is from an Ajax call 
    /// </summary> 
    /// <param name="filterContext">The request context</param> 
    /// <returns>True or false for an Ajax call</returns> 
    private bool IsAjax(ExceptionContext filterContext) 
    { 
     return filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest"; 
    } 
} 

Tengo un CustomException donde puedo comprobar si hay una aplicación de conjunto código de respuesta.

Además, tomo la cadena de consulta, los datos del formulario y el modelo para que pueda ver los valores pasados ​​antes y después de la carpeta del modelo.

Si es y la llamada Ajax, devuelvo una respuesta con formato Json. De lo contrario, devuelvo una página de error personalizada.

Cuestiones relacionadas