Пользовательский шаблон 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 58

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>