Plantilla de validación personalizadaSummary Asp.net MVC 3

Estoy trabajando en un proyecto con Asp.Net MVC3

En una Vista, tengo @Html.ValidationSummary(true) y como siempre produce

 
  • Something bad Happened!

¿Cómo puedo extender este ValidationSummary a MyValidationSummary y producir la plantilla del código HTML algo así como esto?

 

Something bad Happened!

Esta pregunta detalla el procedimiento para escribir un resumen de validación personalizado.

EDITAR Esto hará lo que quieras:

 public static class LinqExt { public static string MyValidationSummary(this HtmlHelper helper, string validationMessage="") { string retVal = ""; if (helper.ViewData.ModelState.IsValid) return ""; retVal += "
"; if (!String.IsNullOrEmpty(validationMessage)) retVal += helper.Encode(validationMessage); retVal += ""; retVal += "
"; foreach (var key in helper.ViewData.ModelState.Keys) { foreach(var err in helper.ViewData.ModelState[key].Errors) retVal += "

" + helper.Encode(err.ErrorMessage) + "

"; } retVal += "
"; return retVal.ToString(); } }

El código es auto explicativo; simplemente enumerando a través de los errores del estado del modelo y envolviendo los errores en el elemento dom de su elección. Hay un error que es si lo uso como:

 <%:Html.MyValidationSummary()%> 

Mostrará tags html en la página como texto en lugar de mostrarlo.

 <%=Html.MyValidationSummary()%> 

Esto funciona bien

Mi enfoque es usar un ValidationSummary.cshtml personalizado:

 @model ModelStateDictionary @if(!Model.IsValid) { 
    @foreach (var modelError in Model.SelectMany(keyValuePair => keyValuePair.Value.Errors)) {
  • @modelError.ErrorMessage
  • }
}

Coloque esta vista parcial en su carpeta compartida y consúltela desde su código:

 @Html.Partial("_ValidationSummary", ViewData.ModelState); 

De esta forma, mantendrá el control total de su html.

Sobre la base de la respuesta de flos , la hice compatible con la validación jQuery Unobtrusive Validation de Microsoft y añadí el estilo de 3 paneles de Bootstrap. Aquí está el nuevo código:

 @model ModelStateDictionary 
Please, correct the following errors:
    @foreach(var modelError in Model.SelectMany(keyValuePair => keyValuePair.Value.Errors)) {
  • @modelError.ErrorMessage
  • }

Puede leer sobre esto con todo detalle aquí:

Crear un ASP.NET MVC @ Html.ValidationSummary personalizado diseñado con el panel Bootstrap 3

También creé un proyecto ASP.NET MVC de muestra para mostrar este ValidationSummary personalizado en acción. Consiguelo aqui:

https://github.com/leniel/AspNetMvcCustomHtmlValidationSummary

Solo publico mi respuesta aquí porque me funciona bien;)

Utilizo un método de extensión simple que toma un MvcHtmlString y lo decodifica de nuevo en HTML:

  public static MvcHtmlString ToMvcHtmlString(this MvcHtmlString htmlString) { if (htmlString != null) { return new MvcHtmlString(HttpUtility.HtmlDecode(htmlString.ToString())); } return null; } 

Para conectar esto, agrego el helper de validación de mi chstml de esta manera:

 @Html.ValidationSummary(true).ToMvcHtmlString() 

Esto significa que puedo agregar HTML personalizado a mis resúmenes de validación:

 ModelState.AddModelError("", "

This message can have html in it

");

E incluso puedo agregar HTML personalizado a mis mensajes de validación de campo:

 ModelState.AddModelError("MyField", "

This message can have html in it

");

Y para que mis mensajes de validación de campo funcionen con HTML:

 @Html.ValidationMessageFor(model => model.MyField).ToMvcHtmlString(); 

Agregar estilos relacionados:

 .field-validation-error { color: #b94a48; } .field-validation-valid { display: none; } input.input-validation-error { border: 1px solid #b94a48; } input[type="checkbox"].input-validation-error { border: 0 none; } .validation-summary-errors { color: #b94a48; } .validation-summary-valid { display: none; } 

Simplemente tuve que hacer algo similar solo para la validación del lado del servidor (por ejemplo, verificar el contenido del archivo) y terminé usurpando por completo el @ Html.ValidationSummary con un buen trabajo.

Tenemos una clase BaseController que extiende el Controlador, y dentro reemplazamos el método OnActionExecuting para varios propósitos. Creamos una nueva lista en ViewBag para nuestros mensajes de error y nos aseguramos de que antes de ejecutar cualquier acción, se inicialice. Luego, podemos agregar nuestros errores para mostrarlos y mostrarlos en la pantalla.

A los fines de esta pregunta, se vería así.

 public class BaseController : Controller { protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (ViewBag.ErrorsList == null) { ViewBag.ErrorsList = new List(); } } } 

Luego en nuestro _Layout.cshtml agregue lo siguiente sobre su @RenderBody ()

 @if(ViewBag.ErrorsList.Count > 0) { 


@foreach (string error in @ViewBag.ErrorsList) { @error
}
@RenderBody() }

Ahora, cada vez que se produce un error en el lado del servidor que queremos mostrar como un mensaje de error de validación, simplemente lo agregamos a nuestro ViewBag.ErrorsList

 ViewBag.ErrorsList.Add("Something bad happened..."); 

Y listo, un contenedor personalizado para sus mensajes de error de validación del lado del servidor con cualquier estilo que desee, con errores pasados ​​de la misma manera que ValidationSummary.

Quería mostrar solo mensajes de nivel superior y nada más. Ya tenemos la validación junto a los campos a continuación. Trabajando con la solución @ Leniel-Macaferi, esto es lo que hice para que funcione con la validación de jQuery: (estilo agregado = “display: none;”)

 
There are still some fields not filled in before we can submit this. Please correct.
    @foreach (var modelError in Model.SelectMany(keyValuePair => keyValuePair.Value.Errors)) {
  • @modelError.ErrorMessage
  • }