title: Fluent Validation in MVC: specify RuleSet for Client-Side validation
body: <p>In my ASP.NET MVC 4 project I have validator for one of my view models, that contain rules definition for RuleSets. <code>Edit</code> ruleset used in Post action, when all client validation passed. <code>Url</code> and <code>Email</code> rule sets rules used in <code>Edit</code> ruleset (you can see it below) and in special ajax actions that validate only Email and only Url accordingly.</p>
  
  <p>My problem is that view doesn't know that it should use <code>Edit</code> rule set for client html attributes generation, and use <code>default</code> rule set, which is empty. <strong>How can I tell view to use <code>Edit</code> rule set for input attributes generation?</strong></p>
  
  <p>Model: </p>
  
  <pre><code>public class ShopInfoViewModel
  {
      public long ShopId { get; set; }
  
      public string Name { get; set; }
  
      public string Url { get; set; }
  
      public string Description { get; set; }
  
      public string Email { get; set; }
  }
  </code></pre>
  
  <p>Validator:</p>
  
  <pre><code>public class ShopInfoViewModelValidator : AbstractValidator&lt;ShopInfoViewModel&gt;
  {
      public ShopInfoViewModelValidator()
      {
          var shopManagementService = ServiceLocator.Instance.GetService&lt;IShopService&gt;();
  
          RuleSet("Edit", () =&gt;
          {
              RuleFor(x =&gt; x.Name)
                  .NotEmpty().WithMessage("Enter name.")
                  .Length(0, 255).WithMessage("Name length should not exceed 255 chars.");
  
              RuleFor(x =&gt; x.Description)
                  .NotEmpty().WithMessage("Enter name.")
                  .Length(0, 10000).WithMessage("Name length should not exceed 10000 chars.");
  
              ApplyUrlRule(shopManagementService);
              ApplyEmailRule(shopManagementService);
          });
  
          RuleSet("Url", () =&gt; ApplyUrlRule(shopManagementService));
          RuleSet("Email", () =&gt; ApplyEmailRule(shopManagementService));
      }
  
      private void ApplyUrlRule(IShopService shopService)
      {
          RuleFor(x =&gt; x.Url)
              .NotEmpty().WithMessage("Enter url.")
              .Length(4, 30).WithMessage("Length between 4 and 30 chars.")
              .Matches(@"[a-z\-\d]").WithMessage("Incorrect format.")
              .Must((model, url) =&gt; shopService.Available(url, model.ShopId)).WithMessage("Shop with this url already exists.");
      }
  
      private void ApplyEmailRule(IShopService shopService)
      {
          // similar to url rule: not empty, length, regex and must check for unique
      }
  }
  </code></pre>
  
  <p>Validation action example:</p>
  
  <pre><code> public ActionResult ValidateShopInfoUrl([CustomizeValidator(RuleSet = "Url")]
          ShopInfoViewModel infoViewModel)
   {
       return Validation(ModelState);
   }
  </code></pre>
  
  <p>Get and Post actions for <code>ShopInfoViewModel</code>:</p>
  
  <pre><code>[HttpGet]
  public ActionResult ShopInfo()
  {
      var viewModel = OwnedShop.ToViewModel();
      return PartialView("_ShopInfo", viewModel);
  }
  
  [HttpPost]
  public ActionResult ShopInfo(CustomizeValidator(RuleSet = "Edit")]ShopInfoViewModel infoViewModel)
      {
          var success = false;
  
          if (ModelState.IsValid)
          {
              // save logic goes here
          }
      }
  </code></pre>
  
  <p>View contains next code:</p>
  
  <pre><code>@{
      Html.EnableClientValidation(true);
      Html.EnableUnobtrusiveJavaScript(true);
  }
  &lt;form class="master-form" action="@Url.RouteUrl(ManagementRoutes.ShopInfo)" method="POST" id="masterforminfo"&gt;
      @Html.TextBoxFor(x =&gt; x.Name)
      @Html.TextBoxFor(x =&gt; x.Url, new { validationUrl = Url.RouteUrl(ManagementRoutes.ValidateShopInfoUrl) })
      @Html.TextAreaFor(x =&gt; x.Description)
      @Html.TextBoxFor(x =&gt; x.Email, new { validationUrl = Url.RouteUrl(ManagementRoutes.ValidateShopInfoEmail) })
      &lt;input type="submit" name="asdfasfd" value="Сохранить" style="display: none"&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>Result html input (without any client validation attributes):</p>
  
  <pre><code>&lt;input name="Name" type="text" value="Super Shop"/&gt; 
  </code></pre>