Asp.net-mvc – ValidationMessage – Handle multiple errors for the same property

asp.net-mvc

I'm using ValidationMessage control in MVC. When validating each property, it may have more than one error message to show, but the ValidationMessage only displays the first error message in the list.

Here is an example:

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

and in the html I have: <%= Html.ValidationMessage("Key")%>

which displays: "Error 1"

I want to see all error messages on the page which will be "Error 1 Error 2"

Any idea how to do it?

Best Solution

I had exactly the same problem, so I created an extension method for HtmlHelper as replacement for the MVC ValidationMessage method.

The benefit of this over ValidationSummary method is that it displays error message per field so you can place it right next to each field (same as ValidationMessage method).

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

Edit: added AllValidationMessageFor method
Edit: added a null check on msgSpan