validationsummary - validationmessage - Plantilla de validación personalizadaSummary Asp.net MVC 3
validationsummary asp.net ejemplo (7)
Estoy trabajando en un proyecto con Asp.Net MVC3
En una Vista, tengo @Html.ValidationSummary(true)
y como siempre produce
<div class="validation-summary-errors">
<ul>
<li>Something bad Happened!</li>
</ul>
</div>
¿Cómo puedo extender este ValidationSummary a MyValidationSummary y producir la plantilla del código HTML algo así como esto?
<div class="notification warning">
<span></span>
<div class="text"> <p>Something bad Happened!</p> </div>
</div>
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;
}
Esta question 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 += "<div class=''notification-warnings''><span>";
if (!String.IsNullOrEmpty(validationMessage))
retVal += helper.Encode(validationMessage);
retVal += "</span>";
retVal += "<div class=''text''>";
foreach (var key in helper.ViewData.ModelState.Keys)
{
foreach(var err in helper.ViewData.ModelState[key].Errors)
retVal += "<p>" + helper.Encode(err.ErrorMessage) + "</p>";
}
retVal += "</div></div>";
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á etiquetas 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)
{
<div class="validation-summary-errors">
<ul>
@foreach (var modelError in
Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
{
<li>@modelError.ErrorMessage</li>
}
</ul>
</div>
}
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.
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;")
<div class="@(Html.ViewData.ModelState.IsValid ? "validation-summary-valid" : "validation-summary-errors")"
data-valmsg-summary="true">
<div>
There are still some fields not filled in before we can submit this. Please correct.
</div>
<div style="display: none;">
<ul>
@foreach (var modelError in Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
{
<li>@modelError.ErrorMessage</li>
}
</ul>
</div>
</div>
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<string>();
}
}
}
Luego en nuestro _Layout.cshtml agregue lo siguiente sobre su @RenderBody ()
@if(ViewBag.ErrorsList.Count > 0)
{
<div class="container margin-top-10 alert alert-danger">
<h3><i class="glyphicon glyphicon-warning-sign"></i></h3><br/>
@foreach (string error in @ViewBag.ErrorsList)
{
@error <br/>
}
</div>
@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.
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
<div class="@(Html.ViewData.ModelState.IsValid ? "validation-summary-valid" : "validation-summary-errors") panel panel-danger"
data-valmsg-summary="true">
<div class="panel-heading">
Please, correct the following errors:
</div>
<div class="panel-body">
<ul>
@foreach(var modelError in Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
{
<li>@modelError.ErrorMessage</li>
}
</ul>
</div>
</div>
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("", "<p>This message can have html in it</p>");
E incluso puedo agregar HTML personalizado a mis mensajes de validación de campo:
ModelState.AddModelError("MyField", "<p>This message can have html in it</p>");
Y para que mis mensajes de validación de campo funcionen con HTML:
@Html.ValidationMessageFor(model => model.MyField).ToMvcHtmlString();