Validation on ViewModels in ASP.NET MVC

后端 未结 2 595
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-01 06:23

Most of the tips on how to implement validation in ASP.NET MVC seem to center around the Model (either building service layers between model and controller or decorating propert

相关标签:
2条回答
  • 2021-02-01 06:53

    The NerdDinner tutorials show the validation as occurring in your partial classes of the model (i.e. Linq to SQL or Entity Framework). But since you're using View Models, you can put the validation logic there.

    The Validation Logic doesn't go in the controller. Rather, it is hooked from the controller with a checking property, i.e. ModelState.IsValid

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(Dinner dinner) {
    
        if (ModelState.IsValid) {
    
            try {
                dinner.HostedBy = "SomeUser";
    
                dinnerRepository.Add(dinner);
                dinnerRepository.Save();
    
                return RedirectToAction("Details", new { id=dinner.DinnerID });
            }
            catch {
                ModelState.AddModelErrors(dinner.GetRuleViolations());
            }
        }
    
        return View(new DinnerFormViewModel(dinner));
    }
    

    Full details are here:

    Building the Model
    http://nerddinnerbook.s3.amazonaws.com/Part3.htm

    and here:

    ViewData and ViewModel
    http://nerddinnerbook.s3.amazonaws.com/Part6.htm

    0 讨论(0)
  • 2021-02-01 07:09

    "Should I put the validation in the ViewModel itself? Or should it stay in the controller" I agree with Robert but I would add a plug for additional automation.

    If you look at a tool such as xVal, you can see that routine validation (e.g., required fields, numbers within ranges, strings matching regular expressions) can be automatically done by decorating fields of your data classes. In fact, xVal can automatically write the JavaScript for routine validations so that it is carried out client side. All without writing any code. Deeper validations (e.g. is this user a member of a domain registered in our database?) happen server-side inside the model layer itself.

    Using the ViewModel idiom can pose some challenges to this scheme. My current approach is to embed my entity objects inside my view model, e.g.

    public class Contact {
        [Required]
        string Name { get; set; }
    }
    
    public class ContactView {
        public Contact Contact { get; set; }
        public string SomeOtherViewProperty { get; set; }
    }
    

    and then in the controller, shallow validation happens when updating the model:

    UpdateModel(contactViewModel.Contact, "Contact");
    

    and the validations requiring more information or more complicated calculations happen inside the model layer itself.

    Another approach is not to embed the entity object but just map individual fields between the two. I've recently become aware of a tool called AutoMapper which automatically links fields between domain and view model objects. It looks like it should support this validation method, though I haven't used it yet.

    0 讨论(0)
提交回复
热议问题