We have an attribute called DateReleased for which the following Data Annotation attributes are added
[Required]
[DataType(DataType.Date, ErrorMessage = "Please enter date")]
[DisplayName("Date Released")]
public object DateReleased { get; set; }
Following is the Action which is implemented to insert a new record to the database
[HttpPost]
public ActionResult Create([Bind(Exclude="Id")] Movie movie)
{
try
{
if (ModelState.IsValid)
{
_entities.AddToMovies(movie);
_entities.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
catch
{
return View();
}
}
I have enabled the client validation, by placing the following lines of code in the create view
<script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.validate.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftAjax.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftMvcAjax.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftMvcValidation.js"></script>
<% Html.EnableClientValidation(); %>
But I was surprised to find that only Required validation is firing on client side. Data Type validation of Date is only firing at server side. Please let me know the reason behind the failure of client side validation and what would be workarounds to fire the client side validation.
Yes. Add a custom attribute class as below
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DateAttribute : DataTypeAttribute
{
public DateAttribute() : base(DataType.Date) { }
public override string FormatErrorMessage(string name)
{
if (ErrorMessage == null && ErrorMessageResourceName == null)
{
ErrorMessage = ValidatorResources.DateAttribute_Invalid;
}
return base.FormatErrorMessage(name);
}
public override bool IsValid(object value)
{
if (value == null) return true;
DateTime retDate;
return DateTime.TryParse(Convert.ToString(value), out retDate);
}
}
Create Client Validation Rule class
public class ModelClientValidationDateRule:ModelClientValidationRule
{
public ModelClientValidationDateRule(string errorMessage)
{
ErrorMessage = errorMessage;
ValidationType = "date";
}
}
Create an adapter class which hooks in the custom attribute and client validation rule as below. Make sure of adding refernce of the above attribute class
public class DateAttributeAdapter : DataAnnotationsModelValidator<DateAttribute>
{
public DateAttributeAdapter(ModelMetadata metadata, ControllerContext context, DateAttribute attribute)
: base(metadata, context, attribute) { }
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
return new[] { new ModelClientValidationDateRule(ErrorMessage) };
}
}
Then modify the global.asax file
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(DateAttribute), typeof(DateAttributeAdapter));
}
Adding the Attribute to the model class as below
[Date]
public object DateReleased { get; set; }
Adding following client side code in the view
<script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.validate.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftAjax.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftMvcAjax.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftMvcValidation.js"></script>
<script type="text/javascript">
Sys.Mvc.ValidatorRegistry.validators["date"] = function (rule) {
// initialization code can go here.
return function (value, context) {
if (value.length > 0) {
var d = new Date(value);
if (!isNaN(d))
return true;
return rule.ErrorMessage;
}
else {
return true;
}
};
};
Hope this would help you.