title: MVC5: Custom Validation on client side not working
body: <p>Based upon this link <a href="https://stackoverflow.com/questions/5816313/mvc3-unobtrusive-validation-group-of-inputs">here</a>
  I made custom validation, its same as the one in link.
  But for me the client side validation doesn't work.</p>
  
  <p>Here is my <strong>validator</strong></p>
  
  <pre><code>public class AtLeastOneRequiredAttribute:ValidationAttribute,IClientValidatable
  {
      private readonly string[] _properties;
      public AtLeastOneRequiredAttribute(params string[] properties)
      {
          _properties = properties;
      }
  
      protected override ValidationResult IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext)
      {
          if (_properties == null || _properties.Length &lt; 1)
          {
              return null;
          }
          foreach (var property in _properties)
          {
              var propertyInfo = validationContext.ObjectType.GetProperty(property);
              if (propertyInfo==null)
              {
                  return  new ValidationResult(string.Format("Unknown property {0}", property));
              }
              var propertyValue = propertyInfo.GetValue(validationContext.ObjectInstance, null);
              if (propertyValue is string &amp;&amp; !string.IsNullOrEmpty(propertyValue as string))
              {
                  return null;
              }
              if (propertyValue !=null)
              {
                  return null;
              }
          }
          return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
      }
  
      public IEnumerable&lt;ModelClientValidationRule&gt; GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
      {
          var rule = new ModelClientValidationRule()
          {
              ErrorMessage = ErrorMessage,
              ValidationType = "atleastonerequired"
          };
          rule.ValidationParameters["properties"] = string.Join(",", _properties);
          yield return rule;
      }
  }
  </code></pre>
  
  <p>Here is the <strong>model</strong>
      public class Person
      {</p>
  
  <pre><code>    [AtLeastOneRequired("FirstName","LastName",ErrorMessage = "*At Least First Name or Last Name is required.")]
      public string FirstName { get; set; }
  
      public string LastName { get; set; }
  
  }
  </code></pre>
  
  <p>Here is the <strong>conroller</strong></p>
  
  <pre><code>[HttpGet]
  public ActionResult AddPerson(int contactId)
  {
      _personRepository.AddPerson(contactId);
      ..
      return PartialView(person);
  }
  
  [HttpPost]
  public ActionResult AddPerson(Person person)
  {
  
      return Content("Success!");
  }
  </code></pre>
  
  <p>and finally the <strong>view</strong></p>
  
  <pre><code>@model WebApplication1.Models.Person
  
  
  &lt;script src="@Url.Content("~/Scripts/jquery.validate.min.js")"&gt;&lt;/script&gt;
  &lt;script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
      jQuery.validator.unobtrusive.adapters.add('atleastonerequired', ['properties'], function(options) {
          options.rules['atleastonerequired'] = options.params;
          options.messages['atleastonerequired'] = options.message;
      });
      jQuery.validator.addMethod('atleastonerequired', function(value, element, params) {
          var properties = params.defineProperties.split(',');
          var values = $.map(properties, function(property, index) {
              var val = $('#' + property).val;
              return val != '' ? val : null;
          });
          return values.length &gt; 0;
      },'');
  &lt;/script&gt;
  
  
  @using(Html.BeginForm("AddPerson","Person",FormMethod.Post))
  {
      @Html.ValidationSummary(false)
      @Html.HiddenFor(m=&gt;m.ContactId)
      &lt;div class="label"&gt;First Name&lt;/div&gt;
      &lt;div class="input-block-level"&gt;@Html.TextBoxFor(m=&gt;m.FirstName)@Html.ValidationMessageFor(m=&gt;m.FirstName)&lt;/div&gt;
      &lt;br/&gt;
      &lt;div class="label"&gt;Last Name&lt;/div&gt;
      &lt;div class="input-block-level"&gt;@Html.TextBoxFor(m=&gt;m.LastName)@Html.ValidationMessageFor(m=&gt;m.LastName)&lt;/div&gt;
      &lt;button type="submit" class="btn-primary"&gt;Submit&lt;/button&gt;
  }
  </code></pre>
  
  <p>I also have <strong>clientvalidation set to true in web.config.</strong>
  Any reason why it is not working?
  When user clicks submit button without filling in any information i was expecting error to be shown on client side, but that doesn't happen and I get forwarded to <strong>HttpPost</strong> method of the controller.</p>
  
  <p>What I have noticed is in view of the provided link inside <code>jQuery.validator.addMethod('atleastonerequired', function(value, element, params)</code> function properties is set as <code>var properties = params.propertynames.split(',');</code> but for me my intellisense in VS2013 doesn't provide <code>params.propertynames</code> it has these two options <code>params.defineProperties</code> and <code>params.originalProperties</code>. </p>
  
  <p>Is that the reason why it is not working?
  What should I do to make my validation work?</p>
  
  <p>Edit1: <strong>Rendered HTML</strong></p>
  
  <pre><code>&lt;script src="/Scripts/jquery-1.8.2.min.js"&gt;&lt;/script&gt;
  &lt;script src="/Scripts/jquery.validate.min.js"&gt;&lt;/script&gt;
  &lt;script src="/Scripts/jquery.validate.unobtrusive.min.js"&gt;&lt;/script&gt;
  &lt;script src="/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"&gt;&lt;/script&gt;
  
  &lt;form action="/" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#partialDiv" id="form0" method="post" novalidate="novalidate"&gt;    &lt;div class="input-block-level"&gt;&lt;input data-val="true" data-val-required="*Search text cannot be empty" id="SearchString" name="SearchString" type="text" value="" class="valid"&gt; &lt;span class="field-validation-valid" data-valmsg-for="SearchString" data-valmsg-replace="true"&gt;&lt;/span&gt; &lt;/div&gt;
      &lt;button type="submit" class="btn-info"&gt;Submit&lt;/button&gt;                              
  &lt;/form&gt;&lt;div id="partialDiv"&gt;
  
  
  
  
  
  &lt;form action="/Person/AddPerson" method="post" novalidate="novalidate"&gt;&lt;div class="validation-summary-valid" data-valmsg-summary="true"&gt;&lt;ul&gt;&lt;li style="display:none"&gt;&lt;/li&gt;
  &lt;/ul&gt;&lt;/div&gt;&lt;input data-val="true" data-val-number="The field ContactId must be a number." data-val-required="The ContactId field is required." id="ContactId" name="ContactId" type="hidden" value="1055"&gt;    &lt;div class="label"&gt;First Name&lt;/div&gt;
      &lt;div class="input-block-level"&gt;&lt;input data-val="true" data-val-atleastonerequired="*At Least First Name or Last Name is required." data-val-atleastonerequired-properties="FirstName,LastName" id="FirstName" name="FirstName" type="text" value=""&gt;&lt;span class="field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="true"&gt;&lt;/span&gt;&lt;/div&gt;
      &lt;br&gt;
      &lt;div class="label"&gt;Last Name&lt;/div&gt;
      &lt;div class="input-block-level"&gt;&lt;input id="LastName" name="LastName" type="text" value=""&gt;&lt;span class="field-validation-valid" data-valmsg-for="LastName" data-valmsg-replace="true"&gt;&lt;/span&gt;&lt;/div&gt;
      &lt;button type="submit" class="btn-primary"&gt;Submit&lt;/button&gt;
  &lt;/form&gt;
  
  
  &lt;/div&gt;
          &lt;hr&gt;
          &lt;footer&gt;
              &lt;p&gt;© 2014&lt;/p&gt;
          &lt;/footer&gt;
      &lt;/div&gt;
  </code></pre>
  
  <p>Edit2: I changed <code>html.textboxfor</code> to <code>html.editorfor</code> in view and removed the <code>html.validationmessagefor</code> but still not working.</p>