问题
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