web-dev-qa-db-fra.com

Récupère toutes les valeurs d'un NameValueCollection dans une chaîne

J'ai le code suivant:

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

J'essayais de jouer avec le get:

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

Mais bien sûr, cela ne fonctionne pas.

J'ai besoin de quelque chose de similaire pour obtenir toutes les valeurs, mais je ne semble pas trouver le code approprié pour faire de même.

P.S: Je ne veux pas utiliser de boucle foreach car cela dépasse le but de la première ligne de code.

34
Dementic
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"

Vous pouvez également créer une méthode d'extension:

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

Usage:

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

De plus, vous pouvez facilement convertir NameValueCollection en Dictionary<string,string> Plus pratique:

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

Donne:

var d = c.ToDictionary();

Comme j'ai trouvé en utilisant Reflector, NameValueCollection.AllKeys Effectue en interne une boucle pour rassembler toutes les clés te, il semble donc que c.Cast<string>() soit plus préférable.

39
abatishchev
string values = string.Join(",", collection.AllKeys.Select(key => collection[key]));
27
Cheng Chen
string values = 
    string.Join(",", FormValues.AllKeys.SelectMany(key => FormValues.GetValues(key)));

Edit: Les autres réponses peuvent ou non être ce que vous voulez. Ils semblent plus simples, mais les résultats peuvent ne pas être ce que vous recherchez dans toutes les circonstances, mais là encore, ils peuvent l'être (votre kilométrage peut varier).

Notez qu'un NameValueCollection n'est pas un mappage 1: 1 comme un dictionnaire. Vous pouvez ajouter plusieurs valeurs pour la même clé, c'est pourquoi une fonction comme .GetValues(key) renvoie un tableau, pas une seule chaîne.

Si vous avez une collection où vous avez ajouté

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

La récupération de collection["Alpha"] Donne "1,2". La récupération de collection.GetValues("Alpha") donne { "1", "2" }. Maintenant, il se trouve que vous utilisez une virgule pour regrouper vos valeurs en une seule chaîne, de sorte que cette disparité est masquée. Cependant, si vous vous associez à une autre valeur, comme un point d'exclamation, les résultats des autres réponses seraient

"1,2!3"

Et le code ici serait

"1!2!3"

Utilisez l'extrait de code qui illustre le comportement que vous préférez.

9
Anthony Pegram

Ce qui suit crée une chaîne à partir de la liste des paramètres d'URL.

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

c'est à dire

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

serait

id: 75, page: 3, size: 7, user: mamaci
9
HGMamaci

Dans les cas où vous avez analysé la chaîne de requête avec System.Web.HttpUtility.ParseQueryString (...), vous pouvez simplement utiliser ToString () et vous n'avez pas à réinventer la roue.

Même si le résultat est NameValueCollection, le type sous-jacent est HttpValueCollection qui a le remplacement ToString () nécessaire pour reconstruire une chaîne de requête.

0
pgk

J'utilise Azure DocumentDB comme mécanisme de journalisation, d'où l'écriture d'un objet dynamique, mais vous obtenez l'essentiel ...

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";
    }
}

J'ai une CustomException où je vérifie un code de réponse défini par l'application.

De plus, je prends la chaîne de requête, les données de formulaire et le modèle afin de pouvoir voir les valeurs passées avant et après le classeur de modèle.

Si son et Ajax appellent, je retourne une réponse au format Json. Sinon, je renvoie une page d'erreur personnalisée.

0
a11smiles