I have created a custom validator deriving from ValidationAttribute. My undertsandng is that it will generate enough meta data for the client side script to automatically validate (using jquery.validate). The custom validator is working fine in server side. But it does not fire error message in the client side. (Other default validators like “StringLength“ are working fine in the client side too.) How do we correct it?
public class Person
{
[Required(ErrorMessage = "First name required")]
public string FirstName { get; set; }
[CustomStartLetterMatch("FirstName")]
[StringLength(5,ErrorMessage = "Must be under 5 characters")]
public string LastName { get; set; }
[Range(18,50,ErrorMessage="Must be between 18 and 50")]
public int Age { get; set; }
}
public sealed class CustomStartLetterMatch : ValidationAttribute
{
private const string _defaultErrorMessage = " First letter of '{0}' must be same as first letetr of '{1}'";
private string _basePropertyName;
public CustomStartLetterMatch(string basePropertyName)
: base(_defaultErrorMessage)
{
_basePropertyName = basePropertyName;
}
//Override FormatErrorMessage Method
public override string FormatErrorMessage(string name)
{
return string.Format(_defaultErrorMessage, name, _basePropertyName);
}
//Override IsValid
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
//Get PropertyInfo Object
var basePropertyInfo = validationContext.ObjectType.GetProperty(_basePropertyName);
var baseValue = (string)basePropertyInfo.GetValue(validationContext.ObjectInstance, null);
var currentValue = (string)value;
string firstLetterBaseValue = baseValue.Substring(0, 1);
string firstLetterCurrentValue = currentValue.Substring(0, 1);
//Comparision
if (!string.Equals(firstLetterBaseValue, firstLetterCurrentValue))
{
var message = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(message);
}
//Default return - This means there were no validation error
return null;
}
}
VIEW
@model MyValidationTEST.Person
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"> </script>
@*UnObtrusive*@
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Person</legend>
<div class="editor-label">
@Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.FirstName)
@Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.LastName)
@Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
READING: