Nerd Dinner validation rules question

2019-09-10 02:32发布

问题:

In the NerdDinner tutorial, Step 5, mid way down under Complete Edit Action Method Implementations there is a paragraph:

The nice thing about our Edit implementation is that neither our Controller class nor our View template has to know anything about the specific validation or business rules being enforced by our Dinner model. We can add additional rules to our model in the future and do not have to make any code changes to our controller or view in order for them to be supported. This provides us with the flexibility to easily evolve our application requirements in the future with a minimum of code changes.

My question is what kind of rule might be added and in such a way that I don't lose my clean separation. I can see this code:

 public static class ControllerHelpers {

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

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

is better than this code:

catch {
    foreach (var issue in dinner.GetRuleViolations()) {
        ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
    }

    return View(dinner);
}

because I do not have specific class/model information and can use it across the application. And, I can see how that is good if my error handling is simple like the above, but I do not see how I would add anything more complex for new business rules and was hoping for an example.

回答1:

First understand that the code you posted really just "pulls" the errors from Model and places them on the View (via the ModelState). The flexibility comes in the fact that any new rules/edits will only need to touch the Model. i.e. you only have to hit the Dinner.cs code.

One thing I had to grok in the NerdDinner lessons was that validation will occur in both the Dinner.cs OnValidate() partial method and in the DinnersController.cs in the call to UpdateModel(). This call copies the text from the screen into the Model. If, for example, it tries to copy text to a float, it will update the ModelState and throw an error. The normal validation will not run.