it-swarm.com.de

Wie Sie alle Fehler von ASP.Net MVC modelState erhalten

Ich möchte alle Fehlermeldungen aus dem modelState erhalten, ohne die Schlüsselwerte zu kennen. Durchsuchen, um alle Fehlernachrichten zu erfassen, die der ModelState enthält.

Wie kann ich das machen?

376
chobo2
foreach (ModelState modelState in ViewData.ModelState.Values) {
    foreach (ModelError error in modelState.Errors) {
        DoSomethingWith(error);
    }
}

Siehe auch Wie erhalte ich die Auflistung von Modellstatusfehlern in ASP.NET MVC? .

455
Oren Trutner

Verwenden von LINQ :

IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors);
452
mmutilva

Aufbauend auf der LINQ-Version, wenn Sie alle Fehlermeldungen in einer Zeichenfolge zusammenfassen möchten:

string messages = string.Join("; ", ModelState.Values
                                        .SelectMany(x => x.Errors)
                                        .Select(x => x.ErrorMessage));
165
Dunc

Ich konnte dies mit einem kleinen LINQ tun, 

public static List<string> GetErrorListFromModelState
                                              (ModelStateDictionary modelState)
{
      var query = from state in modelState.Values
                  from error in state.Errors
                  select error.ErrorMessage;

      var errorList = query.ToList();
      return errorList;
}

Die obige Methode gibt eine Liste von Validierungsfehlern zurück. 

Weiterführende Literatur:

So lesen Sie alle Fehler aus ModelState in ASP.NET MVC

24
Yasser

Beim Debuggen finde ich es nützlich, eine Tabelle am Ende jeder meiner Seiten zu platzieren, um alle ModelState-Fehler anzuzeigen.

<table class="model-state">
    @foreach (var item in ViewContext.ViewData.ModelState) 
    {
        if (item.Value.Errors.Any())
        { 
        <tr>
            <td><b>@item.Key</b></td>
            <td>@((item.Value == null || item.Value.Value == null) ? "<null>" : item.Value.Value.RawValue)</td>
            <td>@(string.Join("; ", item.Value.Errors.Select(x => x.ErrorMessage)))</td>
        </tr>
        }
    }
</table>

<style>
    table.model-state
    {
        border-color: #600;
        border-width: 0 0 1px 1px;
        border-style: solid;
        border-collapse: collapse;
        font-size: .8em;
        font-family: arial;
    }

    table.model-state td
    {
        border-color: #600;
        border-width: 1px 1px 0 0;
        border-style: solid;
        margin: 0;
        padding: .25em .75em;
        background-color: #FFC;
    }
 </style>
13
Simon_Weaver

Wie ich herausgefunden habe, die Ratschläge in den bisherigen Antworten befolgt zu haben, kann es zu Ausnahmen kommen, ohne dass Fehlermeldungen gesetzt werden. Um alle Probleme zu beheben, die Sie wirklich benötigen, um sowohl die Fehlernachricht als auch die Ausnahme zu erhalten.

String messages = String.Join(Environment.NewLine, ModelState.Values.SelectMany(v => v.Errors)
                                                           .Select( v => v.ErrorMessage + " " + v.Exception));

oder als Erweiterungsmethode

public static IEnumerable<String> GetErrors(this ModelStateDictionary modelState)
{
      return modelState.Values.SelectMany(v => v.Errors)
                              .Select( v => v.ErrorMessage + " " + v.Exception).ToList();

}
11
Alan Macdonald

Falls jemand den Namen der Model-Eigenschaft zum Binden der Fehlermeldung in einer stark typisierten Ansicht zurückgeben möchte.

List<ErrorResult> Errors = new List<ErrorResult>();
foreach (KeyValuePair<string, ModelState> modelStateDD in ViewData.ModelState)
{
    string key = modelStateDD.Key;
    ModelState modelState = modelStateDD.Value;

    foreach (ModelError error in modelState.Errors)
    {
        ErrorResult er = new ErrorResult();
        er.ErrorMessage = error.ErrorMessage;
        er.Field = key;
        Errors.Add(er);
    }
}

Auf diese Weise können Sie den Fehler tatsächlich mit dem Feld verknüpfen, das den Fehler ausgelöst hat. 

5
james31rock

Dies erweitert die Antwort von @Dunc. Siehe XML-Dokumentkommentare

// ReSharper disable CheckNamespace
using System.Linq;
using System.Web.Mvc;


public static class Debugg
{
    /// <summary>
    /// This class is for debugging ModelState errors either in the quick watch 
    /// window or the immediate window.
    /// When the model state contains dozens and dozens of properties, 
    /// it is impossible to inspect why a model state is invalid.
    /// This method will pull up the errors
    /// </summary>
    /// <param name="modelState">modelState</param>
    /// <returns></returns>
    public static ModelError[]  It(ModelStateDictionary modelState)
    {
        var errors = modelState.Values.SelectMany(x => x.Errors).ToArray();
        return errors;            
    }
}
4
Chris Marisic

Für den Fall, dass jemand es braucht, habe ich folgende statische Klasse in meinen Projekten verwendet

Verwendungsbeispiel:

if (!ModelState.IsValid)
{
    var errors = ModelState.GetModelErrors();
    return Json(new { errors });
}

Verwendungen:

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using WebGrease.Css.Extensions;

Klasse:

public static class ModelStateErrorHandler
{
    /// <summary>
    /// Returns a Key/Value pair with all the errors in the model
    /// according to the data annotation properties.
    /// </summary>
    /// <param name="errDictionary"></param>
    /// <returns>
    /// Key: Name of the property
    /// Value: The error message returned from data annotation
    /// </returns>
    public static Dictionary<string, string> GetModelErrors(this ModelStateDictionary errDictionary)
    {
        var errors = new Dictionary<string, string>();
        errDictionary.Where(k => k.Value.Errors.Count > 0).ForEach(i =>
        {
            var er = string.Join(", ", i.Value.Errors.Select(e => e.ErrorMessage).ToArray());
            errors.Add(i.Key, er);
        });
        return errors;
    }

    public static string StringifyModelErrors(this ModelStateDictionary errDictionary)
    {
        var errorsBuilder = new StringBuilder();
        var errors = errDictionary.GetModelErrors();
        errors.ForEach(key => errorsBuilder.AppendFormat("{0}: {1} -", key.Key,key.Value));
        return errorsBuilder.ToString();
    }
}
4
CodeArtist

Nur die Fehlermeldungen selbst auszugeben, war für mich nicht ausreichend, aber das gelang. 

var modelQuery = (from kvp in ModelState
                  let field = kvp.Key
                  let state = kvp.Value
                  where state.Errors.Count > 0
                  let val = state.Value.AttemptedValue ?? "[NULL]"

                  let errors = string.Join(";", state.Errors.Select(err => err.ErrorMessage))
                  select string.Format("{0}:[{1}] (ERRORS: {2})", field, val, errors));

Trace.WriteLine(string.Join(Environment.NewLine, modelQuery));
4

Und das funktioniert auch:

var query = from state in ModelState.Values
    from error in state.Errors
    select error.ErrorMessage;
var errors = query.ToArray(); // ToList() and so on...
4
javad amiry

Nützlich für die Übergabe von Fehlernachrichten an View, möglicherweise über Json:

messageArray = this.ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors, (modelState, error) => error.ErrorMessage).ToArray();
2
Steve Lydford

Außerdem kann ModelState.Values.ErrorMessage leer sein, ModelState.Values.Exception.Message kann jedoch einen Fehler anzeigen.

2
Jason Dufair

Ich weiß nicht, dass dies das Problem in meinem Fall ist, manchmal erhalte ich eine Nachricht im ErrorMessage-Abschnitt von ModelState und manchmal in der Ausnahmemeldung des ModelState-Fehlers.

Daher habe ich eine Methode erstellt, die mit beiden Szenarien umgehen kann. Hoffe, das hilft jedem hier.

public static string GetErrorMessageFromModelState(ModelStateDictionary modelState)
    {
        string errorMessage = string.Empty;

        try
        {
            string[] errorMessageList = (from m in modelState
                                         where m.Value.Errors.Count > 0
                                         select string.Join(", ", m.Value.Errors.Select(x =>
                                         !string.IsNullOrEmpty(x.ErrorMessage) ? x.ErrorMessage : !string.IsNullOrEmpty(x.Exception.Message) ?
                                         x.Exception.Message.Split('\'').Length > 0 ? x.Exception.Message.Split('\'')[1].ToString() : m.Key.Split('.').Length > 1 ?
                                         m.Key.Split('.')[1] : m.Key.Split('.')[0] : m.Key.Split('.')[0]))).ToArray();

            errorMessage = string.Format("Error in Field(s): " + string.Join(", ", errorMessageList) + " {0} required.", (errorMessageList.Count() > 1 ? "are" : "is"));
        }
        catch (Exception ex)
        {
            errorMessage = ex.Message;
            if (ex.InnerException != null)
                errorMessage += Environment.NewLine + ex.InnerException;
        }

        return errorMessage;
    }
0
Yagnesh Khamar

In Ihrer Implementierung fehlt die statische Klasse.

if (!ModelState.IsValid)
{
    var errors =  ModelStateErrorHandler.GetModelErrors(this.ModelState);
    return Json(new { errors });
}

lieber

if (!ModelState.IsValid)
{
    var errors = ModelState.GetModelErrors();
    return Json(new { errors });
}
0
Alfred Severo