Validation Summary for Lists using Data Annotations with MVC

Posted by David Liddle on Stack Overflow See other posts from Stack Overflow or by David Liddle
Published on 2010-04-16T16:23:48Z Indexed on 2010/04/16 16:33 UTC
Read the original article Hit count: 782

I currently use a custom method to display validation error messages for lists but would like to replace this system for using with Data Annotations.

In summary on validation of my form, I want to display "*" next to each input that is incorrect and also provide a Validation Summary at the bottom that relates each error message to the particular item in the list.

e.g. say if validation failed on the 2nd list item on a Name input box and the 4th item on an Address input box the validation summary would display

[2] Name is invalid
[4] Address is invalid

Please ignore if there are mistakes in the code below. I'm just writing this as an example.

The code below shows how I was able to do it using my custom version of adding model errors but was wondering how to do this using Data Annotations?

//Domain Object
public class MyObject
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }

    public bool IsValid
    {
        get { return (GetRuleViolations().Count() == 0); }
    }

    public void IEnumerable<RuleViolation> GetRuleViolations()
    {
        if (String.IsNullOrEmpty(Name))
            yield return new RuleViolation(ID, "Name", "Name is invalid");

        if (String.IsNullOrEmpty(Address))
            yield return new RuleViolation(ID, "Address", "Address is invalid");

        yield break;
    }
}

//Rule Violation
public class RuleViolation
{
    public int ID { get; private set; }
    public string PropertyName { get; private set; }
    public string ErrorMessage { get; private set; }
}

//View
<% for (int i = 0; i < 5; i++) { %>
    <p>
        <%= Html.Hidden("myObjects[" + i + "].ID", i) %>

        Name: <%= Html.TextBox("myObjects[" + i + "].Name") %> <br />
        <%= Html.ValidationMessage("myObjects[" + i + "].Name", "*")<br />

        Address: <%= Html.TextBox("myObjects[" + i + "].Address") %> 
        <%= Html.ValidationMessage("myObjects[" + i + "].Address", "*")<br />
    </p>
<% } %>
<p><%= Html.ValidationSummary() %>

//Controller
public ActionResult MyAction(IList<MyObject> myObjects)
{
    foreach (MyObject o in myObjects)
    {
        if (!o.IsValid)
            ModelState.AddModelErrors(o.GetRuleViolations(), o.GetType().Name);
    }

    if (!Model.IsValid)
    {
        return View();
    }
}

public static class ModelStateExtensions
{
    public static void AddModelError(this ModelStateDictionary modelState, 
        RuleViolation issue, string name)
    {
        string key = String.Format("{0}[{1}].{2}", name, issue.ID, issue.PropertyName);
        string error = String.Format("[{0}] {1}", (issue.ID + 1), issue.ErrorMessage);
        //above line determines the [ID] ErrorMessage to be 
        //displayed in the Validation Summary
        modelState.AddModelError(key, error);
    }

© Stack Overflow or respective owner

Related posts about asp.net-mvc

Related posts about dataannotations