134 votes

ASP.NET MVC Comment convertir ModelState erreurs en json

Comment voulez-vous obtenir une liste de tous les ModelState des messages d'erreur? J'ai trouvé ce code pour obtenir toutes les clés: ( http://stackoverflow.com/questions/888521/returning-a-list-of-keys-with-modelstate-errors)

var errorKeys = (from item in ModelState
        where item.Value.Errors.Any() 
        select item.Key).ToList();

Mais comment aurais-je obtenir les messages d'erreur comme un IList IQueryable?

Je pourrais continuer:

foreach (var key in errorKeys)
{
    string msg = ModelState[error].Errors[0].ErrorMessage;
    errorList.Add(msg);
}

Mais c'est de le faire manuellement - il y a sûrement un moyen de le faire à l'aide de LINQ? L' .Propriété ErrorMessage est si loin sur la chaîne que je ne sais pas comment écrire le LINQ...

202voto

SLaks Points 391154

Vous pouvez mettre tout ce que vous voulez à l'intérieur de l' select clause de:

var errorList = (from item in ModelState
        where item.Value.Errors.Any() 
        select item.Value.Errors[0].ErrorMessage).ToList();

EDIT: Vous pouvez extraire plusieurs erreurs en séparer les éléments de la liste par l'ajout d'un from clause, comme ceci:

var errorList = (from item in ModelState.Values
        from error in item.Errors
        select error.ErrorMessage).ToList();

Ou:

var errorList = ModelState.Values.SelectMany(m => m.Errors)
                                 .Select(e => e.ErrorMessage)
                                 .ToList();

2ème ÉDITION: Vous êtes à la recherche pour un Dictionary<string, string[]>:

var errorList = ModelState.ToDictionary(
    kvp => kvp.Key,
    kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
);

77voto

JK. Points 5517

Ici, c'est la pleine mise en œuvre avec tous les morceaux réunis:

D'abord créer une méthode d'extension:

public static class ModelStateHelper
{
    public static IEnumerable Errors(this ModelStateDictionary modelState)
    {
        if (!modelState.IsValid)
        {
            return modelState.ToDictionary(kvp => kvp.Key,
                kvp => kvp.Value.Errors
                                .Select(e => e.ErrorMessage).ToArray())
                                .Where(m => m.Value.Count() > 0);
        }
        return null;
    }
}

Puis appelez la méthode d'extension et de retourner les erreurs de l'action du contrôleur (le cas échéant) de json:

if (!ModelState.IsValid)
{
    return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}

Et puis, finalement, le spectacle de ces erreurs sur le côté client (en jquery.la validation de style, mais peut facilement être changé à n'importe quel autre style)

function DisplayErrors(errors) {
    for (var i = 0; i < errors.length; i++) {
        $("<label for='" + errors[i].Key + "' class='error'></label>")
        .html(errors[i].Value[0]).appendTo($("input#" + errors[i].Key).parent());
    }
}

23voto

Jovica Zaric Points 120

J'aime utiliser Hashtable ici, alors que je reçois objet JSON avec les propriétés que les clés et les erreurs de la valeur sous forme de chaîne de tableau.

var errors = new Hashtable();
foreach (var pair in ModelState)
{
    if (pair.Value.Errors.Count > 0)
    {
        errors[pair.Key] = pair.Value.Errors.Select(error => error.ErrorMessage).ToList();
    }
}
return Json(new { success = false, errors });

De cette façon, vous obtenez la réponse suivante:

{
   "success":false,
   "errors":{
      "Phone":[
         "The Phone field is required."
      ]
   }
}

5voto

h45d6f7d4f6f Points 21

@JK il m'a beaucoup aidé, mais pourquoi pas:

 public class ErrorDetail {

        public string fieldName = "";
        public string[] messageList = null;
 }

        if (!modelState.IsValid)
        {
            var errorListAux = (from m in modelState 
                     where m.Value.Errors.Count() > 0 
                     select
                        new ErrorDetail
                        { 
                                fieldName = m.Key, 
                                errorList = (from msg in m.Value.Errors 
                                             select msg.ErrorMessage).ToArray() 
                        })
                     .AsEnumerable()
                     .ToDictionary(v => v.fieldName, v => v);
            return errorListAux;
        }

2voto

philrabin Points 384

ToDictionary est une Énumération d'extension dans le Système.Linq emballés dans le Système.Web.Extensions dll http://msdn.microsoft.com/en-us/library/system.linq.enumerable.todictionary.aspx. Voici ce que l'complet de la classe ressemble pour moi.

using System.Collections;
using System.Web.Mvc;
using System.Linq;

namespace MyNamespace
{
    public static class ModelStateExtensions
    {
        public static IEnumerable Errors(this ModelStateDictionary modelState)
        {
            if (!modelState.IsValid)
            {
                return modelState.ToDictionary(kvp => kvp.Key,
                    kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()).Where(m => m.Value.Count() > 0);
            }
            return null;
        }

    }

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X