title: ASP.NET MVC FluentValidation with ViewModels and Business Logic Validation
body: <p>I'm exploring using FluentValidation as it seems to be an elegant API for validation of my ViewModels upon model binding.  I'm looking for opinions on how to properly centralize validation using this library as well as from my business (service) layer and raise it up to the view without having 2 different approaches to adding modelstate errors.</p>
  
  <p>I'm open to using an entirely different API but essentially looking to solve this branching validation strategy.  </p>
  
  <p>[Side Note: One thing I tried was to move my business method into my FluentValidation's custom RsvpViewModelValidator class and using the .Must method but it seemed wrong to hide that call in there because if I needed to actually use my Customer object they I would have to re-query it again since its out of scope]</p>
  
  <p>Sample Code:</p>
  
  <pre><code>[HttpPost]
  public ActionResult AcceptInvitation(RsvpViewModel model)
  {
      //FluentValidation has happened on my RsvpViewModel already to check that 
      //RsvpCode is not null or whitespace
      if(ModelState.IsValid)
      {
          //now I want to see if that code matches a customer in my database.
          //returns null if not, Customer object if existing
          customer = _customerService.GetByRsvpCode(model.RsvpCode);
          if(customer == null)
          {
              //is there a better approach to this?  I don't like that I'm
              //splitting up the validation but struggling up to come up with a 
              //better way.
              ModelState.AddModelError("RsvpCode", 
                  string.Format("No customer was found for rsvp code {0}", 
                                model.RsvpCode);
  
              return View(model);
          }
  
          return this.RedirectToAction(c =&gt; c.CustomerDetail());
      }
  
      //FluentValidation failed so should just display message about RsvpCode 
      //being required
      return View(model);
  }
  
  [HttpGet]
  public ActionResult CustomerDetail()
  {
       //do work.  implementation not important for this question.
  }
  </code></pre>