views:

933

answers:

2

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?

+9  A: 

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;
    }
}
griegs
I did not have using NerdDinner.Helpers;However, I don't see why not having that makes it not work.I must be missing some fundamental knowledge about how C# works...
metanaito
Yup, I totally did not understand what an extension method was. This URL cleared it up for me:http://msdn.microsoft.com/en-us/library/bb311042.aspxThanks for the help!
metanaito
You need to include the reference to the Namespace else .Net won't know where your Helper class is.
griegs
An extension method is just a static method with an easier to read syntax. This is why you need to add the using directive for the namespace where the extension method is defined.ModelState.AddModelErrors(dinner.GetRuleViolations()); is the same as ModelStateHelpers.AddModelErrors(ModelState, dinner.GetRuleViolations());
Ben Robbins
Thanks Ben. I know this now.I was trying something like ModelStateHelpers.AddModelErrors(dinner.GetRuleViolations());That obviously doesn't work with just 1 argument. I couldn't figure out how it could be called with just 1 argument... but now I understand why. Pretty neat!
metanaito
+3  A: 

If you are receiving the same error message as this poster:

"'System.Web.Mvc.ModelStateDictionary' does not contain a definition for 'AddModelErrors' and no extension method 'AddModelErrors' accepting a first argument of type 'System.Web.Mvc.ModelStateDictionary' could be found (are you missing a using directive or an assembly reference?)"

You may be having this problem:

http://p2p.wrox.com/book-professional-asp-net-mvc-1-0-isbn-978-0-470-38461-9/74321-addmodalerrors-allcountries-page-87-view-data-dictionary.html#post248356

KPHutt
Thank you. That wasn't the issue here but good to point out there are some errors in the sample. My issue was that I just didn't understand what an extension method is...
metanaito