Пользовательский шаблон ValidationSummary Asp.net MVC 3
Я работаю над проектом с Asp.Net MVC3
В представлении у меня есть @Html.ValidationSummary(true)
и как обычно он выдает
<div class="validation-summary-errors">
<ul>
<li>Something bad Happened!</li>
</ul>
</div>
как я могу расширить этот ValidationSummary на MyValidationSummary и создать шаблон Html-кода примерно так:
<div class="notification warning">
<span></span>
<div class="text"> <p>Something bad Happened!</p> </div>
</div>
7 ответов:
этой вопрос сведения о процедуре написания резюме проверки.
EDIT Это будет делать то, что вы хотите:
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(); } }
код не требует пояснений; просто перечисляя ошибки modelstate и ошибки обертывания в элементе dom по вашему выбору. Есть ошибка, если я использую его как:
<%:Html.MyValidationSummary()%>
он будет отображать HTML-теги на странице в виде текста, а не рендеринга.
<%=Html.MyValidationSummary()%>
это работает штраф.
мой подход заключается в использовании пользовательским
ValidationSummary.cshtml
:@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> }
поместите это частичное представление в общую папку и обратитесь к нему из своего кода:
@Html.Partial("_ValidationSummary", ViewData.ModelState);
таким образом, вы остаетесь в полном контроле над вашим html.
на ответ флоса, Я сделал его совместимым с ненавязчивой проверкой Microsoft jQuery и добавил стиль панели Bootstrap 3. Вот новый код:
@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>
вы можете прочитать об этом подробно здесь:
создание пользовательского ASP.NET MVC @Html.ValidationSummary в стиле Bootstrap 3 panel
Я также создал образец ASP.NET проект MVC, чтобы показать этот пользовательский ValidationSummary в действии. Получить его здесь:
https://github.com/leniel/AspNetMvcCustomHtmlValidationSummary
просто разместите мой ответ здесь, потому что он хорошо работает для меня ;)
Я использую простой метод расширения, который принимает
MvcHtmlString
и декодирует его обратно в HTML:public static MvcHtmlString ToMvcHtmlString(this MvcHtmlString htmlString) { if (htmlString != null) { return new MvcHtmlString(HttpUtility.HtmlDecode(htmlString.ToString())); } return null; }
чтобы отвесить это, я добавляю помощник сводки проверки к моему chstml следующим образом:
@Html.ValidationSummary(true).ToMvcHtmlString()
это означает, что я могу добавить пользовательский HTML в мои резюме проверки:
ModelState.AddModelError("", "<p>This message can have html in it</p>");
и я даже могу добавить пользовательский HTML в мои сообщения проверки полей:
ModelState.AddModelError("MyField", "<p>This message can have html in it</p>");
и получить мои сообщения проверки для работы с HTML:
@Html.ValidationMessageFor(model => model.MyField).ToMvcHtmlString();
добавить соответствующие стили:
.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; }
Я просто должен был сделать что-то подобное только для проверки на стороне сервера ( например, проверка содержимого файла) и в конечном итоге полностью узурпировал @Html.ValidationSummary в целом с довольно приятной небольшой работой вокруг.
у нас есть класс BaseController, который расширяет контроллер, и внутри мы переопределяем метод OnActionExecuting для нескольких целей. Мы создаем новый список в ViewBag для наших сообщений об ошибках и гарантируем, что перед выполнением любого действия он будет инициализирован. Тогда мы можем добавить наши ошибки, которые будут отображаться на нем, и отображать на экране.
для целей этого вопроса это будет выглядеть так.
public class BaseController : Controller { protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (ViewBag.ErrorsList == null) { ViewBag.ErrorsList = new List<string>(); } } }
тогда в нашем _Layout.cshtml добавьте следующее над вашим @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() }
Теперь всякий раз, когда возникает ошибка на стороне сервера, которую мы хотим отобразить в качестве сообщения об ошибке проверки, мы просто добавляем его в наш ViewBag.ErrorsList
ViewBag.ErrorsList.Add("Something bad happened...");
и вуаля, один пользовательский контейнер для ошибки проверки на стороне сервера сообщения с любыми стилями, которые вы хотите на нем, с ошибками, переданными таким же образом, как ValidationSummary.
Я хотел показать только сообщение верхнего уровня и ничего больше. У нас уже есть проверка рядом с полями ниже. Отработка решения @Leniel-Macaferi это то, что я сделал, чтобы заставить его работать с проверкой jQuery: (добавлен стиль="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>