ValidationSummary displays duplicate messages

二次信任 提交于 2019-12-04 12:55:39

They are not duplicate from the point of view of ValidationSummary - you are assigning model state error to both fields A and B, so there must be 2 errors in validation summary. It doesnt "know" that they are the same.

Easy solutions :

  • assign model only to one of them
  • exclude property-assigned errors from summary - Html.ValidationSummary(true)

A little bit harder solution :

  • make your own ValidationSummary helper, call standard validation summary logic in it, and then filter the result in "select distinct" way (linq is your friend here).

EDIT:

something like this for example :

public static class ValidationExtensions
{
    public static MvcHtmlString FilteredValidationSummary(this HtmlHelper html)
    {
        // do some filtering on html.ViewData.ModelState 
        return System.Web.Mvc.Html.ValidationExtensions.ValidationSummary(html);
    }
}

Whack this is your View

<ul class="validation-summary-errors">
    @{
        string errorMessage = "", previousError = "";
        foreach (ModelState modelState in (ViewContext.ViewData.ModelState.Values)){

            foreach (ModelError modelError in modelState.Errors)
            {
                errorMessage = modelError.ErrorMessage;
                if (errorMessage != previousError)
                {
                    <li>@modelError.ErrorMessage</li>
                    previousError = modelError.ErrorMessage;
                }                            
            }    
        }
    }
</ul>

You might be able to improve this as it only works when 2 consecutive errors are the same, if it jumbles the order this might not work, but this will start you off. I suppose you could build an array of error messages and check the error off it each run through, but this solution seems to work most of the time.

ValidationSummary method returns property-level and model-level errors. It just enumerates all validation messages if you don't specify any arguments.

You can: 1) Use different message for field A and B

// logic here
yield return new ValidationResult("Validation failed for left field", new[] { "A" });
// logic here
yield return new ValidationResult("Validation failed for right field", new[] { "B" });

or, in your view

2) Call ValidationSummary with excludePropertyErrors argument set to true - ValidationSummary(true). And place call Html.ValidationMessage[For] near each of your fields.

UPDT: ... and third case:

In your model add common message (model-level):

//logic here
yield return new ValidationResult("Validation failed");
yield return new ValidationResult("any text or empty string", new[] { "A", "B" });

In your view exclude property messages but don't add ValidationMessage for fields:

@model MyModel
@Html.ValidationSummary(true)
@Html.TextBoxFor(model => model.A)
@Html.TextBoxFor(model => model.B)

So you'll get single message and both red boxes.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!