¿Cómo obtengo la colección de errores de estado del modelo en ASP.NET MVC?


145

¿Cómo obtengo la colección de errores en una vista?

No quiero usar el Resumen de validación de ayuda HTML o el Mensaje de validación. En cambio, quiero verificar si hay errores y, si los hay, mostrarlos en un formato específico. También en los controles de entrada quiero verificar un error de propiedad específico y agregar una clase a la entrada.

PD: Estoy usando el Spark View Engine pero la idea debería ser la misma.

Entonces pensé que podría hacer algo como ...

<if condition="${ModelState.Errors.Count > 0}">
  DispalyErrorSummary()
</if>

....and also...

<input type="text" value="${Model.Name}" 
       class="?{ModelState.Errors["Name"] != string.empty} error" />

....

O algo así.

ACTUALIZAR

Mi solución final se veía así:

<input type="text" value="${ViewData.Model.Name}" 
       class="text error?{!ViewData.ModelState.IsValid && 
                           ViewData.ModelState["Name"].Errors.Count() > 0}" 
       id="Name" name="Name" />

Esto solo agrega la clase de error css si esta propiedad tiene un error.


Respuestas:


210
<% ViewData.ModelState.IsValid %>

o

<% ViewData.ModelState.Values.Any(x => x.Errors.Count >= 1) %>

y para una propiedad específica ...

<% ViewData.ModelState["Property"].Errors %> // Note this returns a collection

1
la propiedad ModelState es de tipo diccionario para obtener el error de pasar el nombre de clave ViewData.ModelState ["Name"]

con respecto a "ViewData.ModelState [" Propiedad "]. Errores" ¿arrojaría esto una excepción de referencia nula si no hubiera una clave con el nombre "Propiedad"? ¿sería mejor verificar primero si hay valores nulos en ViewData.ModelState ["Propiedad"] antes de leer los Errores?
David Hollowell - MSFT

@DaveH Sí, primero debes verificar por completo la existencia
Alex Lyman

61

Para obtener solo los errores de ModelState, use este Linq:

var modelStateErrors = this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors);

2
¿arrojaría esto una excepción de referencia nula si no hubiera una clave con el nombre especificado? ¿sería mejor comprobar primero si hay valores nulos en la [clave] ViewData.ModelState antes de leer los errores?
David Hollowell - MSFT

55
Debido a que comenzamos iterando sobre esto.ModelState.Keys, no veo el potencial para una KeyNotFoundException. Creo que ese cheque sería exagerado.
Chris McKenzie


28

Esto le dará una cadena con todos los errores con separación de comas

string validationErrors = string.Join(",",
                    ModelState.Values.Where(E => E.Errors.Count > 0)
                    .SelectMany(E => E.Errors)
                    .Select(E => E.ErrorMessage)
                    .ToArray());

¡Esto es lo único que encontré en toda esta lista que realmente imprime los errores! Gracias
Jamie

6

Gracias Chad! Para mostrar todos los errores asociados con la clave, esto es lo que se me ocurrió. Por alguna razón, el asistente base Html.ValidationMessage solo muestra el primer error asociado con la clave.

    <%= Html.ShowAllErrors(mykey) %>

HtmlHelper:

    public static String ShowAllErrors(this HtmlHelper helper, String key) {
        StringBuilder sb = new StringBuilder();
        if (helper.ViewData.ModelState[key] != null) {
            foreach (var e in helper.ViewData.ModelState[key].Errors) {
                TagBuilder div = new TagBuilder("div");
                div.MergeAttribute("class", "field-validation-error");
                div.SetInnerText(e.ErrorMessage);
                sb.Append(div.ToString());
            }
        }
        return sb.ToString();
    }

6

Al reunir varias respuestas de lo anterior, esto es lo que terminé usando:

var validationErrors = ModelState.Values.Where(E => E.Errors.Count > 0)
    .SelectMany(E => E.Errors)
    .Select(E => E.ErrorMessage)
    .ToList();

validationErrorstermina siendo un List<string>mensaje que contiene cada mensaje de error. A partir de ahí, es fácil hacer lo que quieras con esa lista.

ingrese la descripción de la imagen aquí


2

Aquí está el VB.

Dim validationErrors As String = String.Join(",", ModelState.Values.Where(Function(E) E.Errors.Count > 0).SelectMany(Function(E) E.Errors).[Select](Function(E) E.ErrorMessage).ToArray())

0

Si no sabe qué propiedad causó el error, puede, usando la reflexión, recorrer todas las propiedades:

public static String ShowAllErrors<T>(this HtmlHelper helper) {
    StringBuilder sb = new StringBuilder();
    Type myType = typeof(T);
    PropertyInfo[] propInfo = myType.GetProperties();

    foreach (PropertyInfo prop in propInfo) {
        foreach (var e in helper.ViewData.ModelState[prop.Name].Errors) {
            TagBuilder div = new TagBuilder("div");
            div.MergeAttribute("class", "field-validation-error");
            div.SetInnerText(e.ErrorMessage);
            sb.Append(div.ToString());
        }
    }
    return sb.ToString();
}

Donde T es el tipo de su "ViewModel".

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.