Пользовательский шаблон ValidationSummary Asp.net MVC 3 - PullRequest
61 голосов
/ 02 мая 2011

Я работаю над проектом с 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 ]

133 голосов
/ 16 декабря 2011

Мой подход заключается в использовании пользовательского 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.

45 голосов
/ 02 мая 2011

В этом вопросе подробно описана процедура написания пользовательского резюме проверки.

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();
    }
}

Код не требует пояснений; просто перечисление ошибок состояния модели и ошибок переноса в элемент dom по вашему выбору. Есть ошибка, если я использую ее как:

<%:Html.MyValidationSummary()%>

Он будет отображать HTML-теги на странице в виде текста, а не отображать его.

<%=Html.MyValidationSummary()%>

Это отлично работает.

22 голосов
/ 30 августа 2013

Основываясь на ответе flos , я сделал его совместимым с ненавязчивой проверкой Microsoft jQuery и добавил 3 панели Bootstrap.Вот новый код:

@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

Я также создал пример проекта ASP.NET MVC, чтобы показать эту пользовательскую ValidationSummary в действии.Получите это здесь:

https://github.com/leniel/AspNetMvcCustomHtmlValidationSummary

2 голосов
/ 12 марта 2014

Просто выкладываю мой ответ здесь, потому что он хорошо работает для меня;)

Я использую простой метод расширения, который берет 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();
1 голос
/ 05 ноября 2015

Мне просто нужно было сделать что-то похожее только для проверки на стороне сервера (например, проверить содержимое файла), и в итоге мы полностью узурпировали @ Html.ValidationSummary вместе с довольно приятной небольшой работой.

Мыу нас есть класс BaseController, расширяющий Controller, и внутри мы переопределяем метод 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.

1 голос
/ 16 июня 2015

Добавление связанных стилей:

.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;
}
0 голосов
/ 29 мая 2014

Я хотел показать только сообщение верхнего уровня и больше ничего.У нас уже есть проверка рядом с полями ниже.Отрабатывая решение @ 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>
...