c# - Obtener todos los valores de NameValueCollection en una cadena
.net (7)
A continuación se crea una cadena de la lista de parámetros de 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
sería
id: 75, page: 3, size: 7, user: mamaci
Tengo el siguiente código:
string Keys = string.Join(",",FormValues.AllKeys);
Estaba tratando de jugar con el get:
string Values = string.Join(",", FormValues.AllKeys.GetValue());
Pero claro que eso no funciona.
Necesito algo similar para obtener todos los valores, pero parece que no encuentro el código adecuado para hacer lo mismo.
PD: no quiero usar un bucle foreach
ya que supera el propósito de la primera línea de código.
En los casos en los que haya analizado la cadena de consulta con System.Web.HttpUtility.ParseQueryString (...) puede usar ToString () y no tiene que reinventar la rueda.
A pesar de que el resultado es NameValueCollection, el tipo subyacente es HttpValueCollection que tiene la anulación necesaria ToString () para reconstruir una cadena de consulta.
Estoy usando Azure DocumentDB como mi mecanismo de registro, por lo tanto, estoy escribiendo un objeto dinámico, pero obtienes la esencia ...
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 una excepción personalizada en la que compruebo un código de respuesta de conjunto de aplicaciones.
Además, tomo la cadena de consulta, los datos de formulario y el modelo para que pueda ver los valores pasados antes y después de la carpeta del modelo.
Si es y Ajax llama, devuelvo una respuesta con formato Json. De lo contrario, devuelvo una página de error personalizada.
List<string> values = new List<string>();
values.AddRange(all.AllKeys.SelectMany(all.GetValues).Where(getValues => getValues != null));
string Values = string.Join(",", values.ToArray());
Puedes probar algo como lo anterior.
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 serlo (su millaje puede variar).
Tenga en cuenta que NameValueCollection
no es una asignación 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 tienes una colección donde has añadido
collection.Add("Alpha", "1");
collection.Add("Alpha", "2");
collection.Add("Beta", "3");
Al recuperar la collection["Alpha"]
obtiene "1,2"
. Al recuperar collection.GetValues("Alpha")
obtiene { "1", "2" }
. Ahora, da la casualidad de que está utilizando una coma para unir sus valores en una sola cadena, por lo que esta disparidad está oculta. Sin embargo, si se uniera a 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ía
"1!2!3"
Usa el fragmento que demuestra el comportamiento que prefieres.
string values = string.Join(",", collection.AllKeys.Select(key => collection[key]));
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 puedes 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 puedes convertir fácilmente NameValueCollection
en un Dictionary<string,string>
más práctico Dictionary<string,string>
así que:
public static IDictionary<string,string> ToDictionary(this NameValueCollection col)
{
return col.AllKeys.ToDictionary(x => x, x => col[x]);
}
Da:
var d = c.ToDictionary();
Como encontré usando Reflector, NameValueCollection.AllKeys
realiza internamente un bucle para reunir todas las claves te, por lo que parece que c.Cast<string>()
es más preferible.