ValidationMessage - обрабатывать несколько ошибок для одного свойства - PullRequest
8 голосов
/ 05 июня 2009

Я использую контроль ValidationMessage в MVC. При проверке каждого свойства может отображаться несколько сообщений об ошибках, но ValidationMessage отображает только первое сообщение об ошибке в списке.

Вот пример:

ModelState["Key"] = new ModelState();
ModelState["Key"].Errors.Add("Error 1");
ModelState["Key"].Errors.Add("Error 2");

и в HTML у меня есть: <%= Html.ValidationMessage("Key")%>

, который отображает: "Error 1"

Я хочу видеть все сообщения об ошибках на странице, которые будут "Error 1 Error 2"

Есть идеи, как это сделать?

Ответы [ 6 ]

6 голосов
/ 29 июня 2010

У меня была точно такая же проблема, поэтому я создал метод расширения для HtmlHelper в качестве замены для метода MVC ValidationMessage.

Преимущество этого метода перед ValidationSummary заключается в том, что он отображает сообщение об ошибке для каждого поля, поэтому вы можете разместить его рядом с каждым полем (так же, как метод ValidationMessage).

public static string AllValidationMessage(this HtmlHelper helper, string modelName)
{
    StringBuilder builder = new StringBuilder();
    TagBuilder ulTag = new TagBuilder("ul");
    ulTag.AddCssClass("u-error-list");

    builder.Append(ulTag.ToString(TagRenderMode.StartTag));
    if (helper.ViewData.ModelState.ContainsKey(modelName) &&
        helper.ViewData.ModelState[modelName].Errors.Count > 0)
    {
        foreach (var err in helper.ViewData.ModelState[modelName].Errors)
        {
            TagBuilder liTag = new TagBuilder("li") { InnerHtml = HttpUtility.HtmlEncode(err.ErrorMessage) };
            liTag.AddCssClass("u-error-item");
            builder.Append(liTag.ToString());
        }
    }
    builder.Append(ulTag.ToString(TagRenderMode.EndTag));

    var msgSpan = helper.ValidationMessage(modelName, "{placeholder}");

    if (msgSpan == null)
        return string.Empty;

    return msgSpan.ToHtmlString().Replace("{placeholder}", builder.ToString());
}

public static string AllValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
    return HtmlHelperExtensions.AllValidationMessage(helper, ExpressionHelper.GetExpressionText(expression));
}

Редактировать : добавлен метод AllValidationMessageFor *
Редактировать : добавлена ​​нулевая проверка на msgSpan

2 голосов
/ 05 июня 2009

С помощью готового MVC вам нужно добавить ValidationSummary:

<%= Html.ValidationSummary() %>

Это покажет все ModelErrors.

1 голос
/ 24 октября 2017

Более прямой подход к точке:

Контроллер:

ModelState.AddModelError("other", "error 1");
ModelState.AddModelError("other", "error 2");
ModelState.AddModelError("other", "error 3");

Вид:

<ul>
    @foreach (var error in Html.ViewData.ModelState["other"].Errors)
    {
        <li>@error.ErrorMessage</li>
    }
</ul>
1 голос
/ 26 марта 2014

Поскольку ModelState следует шаблону словаря для ошибок, кажется, что в конечном итоге нам нужно объединить все ошибки в один ключ ModelState:

   ModelState["Key"].Errors.Add("Error 1. " + "Error 2");

Если вы используете IValidatableObject соглашение для выполнения пользовательских проверок, вы можете преобразовать ошибки результата проверки в ModelState записи следующим образом:

var resultsGroupedByMembers = validationResults
    .SelectMany(_ => _.MemberNames.Select(
         x => new {MemberName = x ?? "", 
                   Error = _.ErrorMessage}))
    .GroupBy(_ => _.MemberName);

foreach (var member in resultsGroupedByMembers)
{
    ModelState.AddModelError(
        member.Key,
        string.Join(". ", member.Select(_ => _.Error)));
}

Необходимо перекрестное соединение, учитывая, что может быть более одного MemberName на результат проверки. Несвязанные результаты связаны с "" и должны быть доступны для ValidationSummary.

1 голос
/ 28 марта 2013

Основываясь на решениях, представленных здесь и в Как отобразить несколько ошибок проверки с помощью @ Html.ValidationMessageFor? , я создал собственное многострочное сообщение проверки для свойства. Он ведет себя как ValidationSummary, но может использоваться для каждого поля. Я использую его для представления сообщения проверки поля коллекции модели. Это позволяет мне представить сводное сообщение для коллекции и только для коллекции.

public static MvcHtmlString MultilineValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
{
    var propertyName = ExpressionHelper.GetExpressionText(expression);
    var modelState = htmlHelper.ViewData.ModelState;

    // If we have multiple (server-side) validation errors, collect and present them.
    if (modelState.ContainsKey(propertyName) && modelState[propertyName].Errors.Count > 1)
    {
        var msgs = new StringBuilder();
        foreach (ModelError error in modelState[propertyName].Errors)
        {
            msgs.AppendLine(error.ErrorMessage + "<br />");
        }

        // Return standard ValidationMessageFor, overriding the message with our concatenated list of messages.
        var msgSpan = htmlHelper.ValidationMessageFor(expression, "{0}", htmlAttributes as IDictionary<string, object> ?? htmlAttributes);
        var msgDiv = msgSpan.ToHtmlString().Replace("span", "div");

        return new MvcHtmlString(string.Format(msgDiv, msgs.ToString()));
    }

    // Revert to default behaviour.
    return htmlHelper.ValidationMessageFor(expression, null, htmlAttributes as IDictionary<string, object> ?? htmlAttributes);
}
0 голосов
/ 05 июня 2009

Также в вашем действии контроллера вы можете проверить

ModelState.IsValid

и если оно ложно, просто верните View, и ValidationSumary будет заполнен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...