After a lot of Googling I found the right way of doing what I want:
Model Validation in ASP.NET MVC 3
To validate (ie. find duplicate entries) in a collection/list property in your ViewModel
you must add a
@Html.ValidationMessageFor(u => u.Idioms)
for the property in your View
and compose the errorMessage
inside the Validate
method. Finally assign the message to the correct property name, that is, Idioms
in my case.
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var grouping = Idioms.GroupBy(ui => ui.Idiom);
var duplicates = grouping.Where(group => group.Count() > 1);
if(duplicates.Any())
{
string message = string.Empty;
foreach(var duplicate in duplicates)
{
message += string.Format("{0} was selected {1} times", duplicate.Key, duplicate.Count());
}
yield return new ValidationResult(message, new[] { "Idioms" });
}
}
BONUS
If you want to display each duplicate group in separate lines
(adding line breaks <br>
), do this:
Replace {0} was selected {1} times
with {0} was selected {1} times<br>
and then on the View
side do this:
@Html.Raw(HttpUtility.HtmlDecode(Html.ValidationMessageFor(u => u.Idioms).ToHtmlString()))
Output will be:
French was selected 2 times
English was selected 3 times