ValidationSummary displays duplicate messages

Deadly 提交于 2019-12-21 20:27:33

问题


If two of textboxes fail validation at once then the ValidationSummary displays the same message twice.

Am I doing something wrong? Or is there a setting I can change to hide duplicate messages?

 

I have broken it down to the simplest example:

View:

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

Model:

public class MyModel : IValidatableObject
{
    public int A { get; set; }
    public int B { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        //Some logic goes here.        
        yield return new ValidationResult("Validation failed", new[] { "A", "B" });
    }
}

Result:


回答1:


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



回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/7766749/validationsummary-displays-duplicate-messages

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