asp.net-mvcextension-methodsnerddinner

How does NerdDinner's AddModelErrors work?


I'm going through the NerDinner free tutorial http://nerddinnerbook.s3.amazonaws.com/Intro.htm

I got to somewhere in Step 5 where it says to make the code cleaner we can create an extension method. I look at the completed code and it has this to use the extension method:

catch
{
    ModelState.AddModelErrors(dinner.GetRuleViolations());
    return View(new DinnerFormViewModel(dinner));
}

And then this as the extension method's definition.

namespace NerdDinner.Helpers {

    public static class ModelStateHelpers {

        public static void AddModelErrors(this ModelStateDictionary modelState, IEnumerable<RuleViolation> errors) {

            foreach (RuleViolation issue in errors) {
                modelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
            }
        }
    }
}

I try to follow what the tutorial says combined with what the code contains but receive the expected error that there is no AddModelErrors method that accepts only 1 argument.

I'm obviously missing something very important here. What is it?


Solution

  • You need to include the helpers reference;

    using NerdDinner.Helpers;
    

    and

    using NerdDinner.Models;
    

    Then check for valid and add the errors;

    if (!dinner.IsValid)
    {
        ModelState.AddModelErrors(dinner.GetRuleViolations());
        return View(dinner);
    }
    

    You must also have a partial class for your dinner;

    public partial class Dinner
    {
        public bool IsValid
        {
            get { return (GetRuleViolations().Count() == 0); }
        }
    
        public IEnumerable<RuleViolation> GetRuleViolations()
        {
            if (String.IsNullOrEmpty( SomeField ))
                yield return new RuleViolation("Field value text is required", "SomeField");
        }
    
        partial void OnValidate(ChangeAction action)
        {
            if (!IsValid)
                throw new ApplicationException("Rule violations prevent saving");
        }
    }
    

    Don't forget the RuleViolation class;

    public class RuleViolation
    {
        public string ErrorMessage { get; private set; }
        public string PropertyName { get; private set; }
    
        public RuleViolation(string errorMessage)
        {
            ErrorMessage = errorMessage;
        }
    
        public RuleViolation(string errorMessage, string propertyName)
        {
            ErrorMessage = errorMessage;
            PropertyName = propertyName;
        }
    }