Hi, I am using MVC 3 unobtrusive client side validation and I need to implement some custom validation rules for my DateTime field.
I got ExpiryDate and Storagedate, where Expirydate should be later or equal to today's date. Also, the Expirydate should not be earlier than the StorageDate.
However, I got no idea how to implement the custom validation. I got the partial class to customize the validation in my Model like this:
[MetadataType(typeof(FoodMetaData))]
public partial class FOOD
{
[Bind(Exclude = "FoodID")]
public class FoodMetaData
{
[ScaffoldColumn(false)]
public int FoodID { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Please enter a name")]
public object FoodName { get; set; }
public object StorageDate { get; set; }
public object ExpiryDate { get; set; }
}
}
Any idea how can I declare a custom validation for the DateTime field?? I googled a lot but still no able to find similar solution... Please help...
Use the
DateTimeInput and the
DateRangeAttribute of my Mvc Controls Toolkit. You can define both the previous constraint, on the client side and on the server side, easily by placing two DateRange attributes on the ExpiryDate each for each constraint and by adding a new property called
ToDay to your ViewModel (it has just a get returning today). User would not be able to enter a date is nort allowed at all. You have also the option, when the user choose a storageDate, to change expiryDate automatically to make the constraint holds instead
of limiting the value of ExpiryDate.
The example application here show an example of use. Other examples of the use of the DateTimeInput are...pratically in almost all tutorials.
Because I need something like [DateRange(SMaximum =
"2012-1-1", SMinimum = "2008-1-1")] but if for ExpiryDate, i only need the minimum part which is Today's date && StorageDate. I not really understand how to do this since there is no example available there..
There are examples....you have to see the ViewModel used in the page of the software distribution. Anyway:
1) define a property you call Today (for example):
[Milestone]
public DateTime Today {
get{
return DateTime.Now;
}
}
please notoce the milestone attribute, this inform the engine that the proprty will not be renderedi in the page;
now you write:
[DateTange(DynamicMinimum='Today')]
[DateTange(DynamicMinimum='StorageDate')]
public DateTime ExpiryDate{get; set;}
This way when user will introduce a wrong date the date will be automatically corrected to match the constraint.
if you use [DateTange(DynamicMinimum='StorageDate', RangeAction = RangeAction.Propagate)]
instead when user will introduce e data that is smaller than ExpiryDate ExpiriDate will be decreased in the Html page to keep the constraint valid.
Th minimum you have define are called Dinamic because they depends on the value of other properties. I suggest to addr also some fixed minimum and fixed maximum, say 1900 and 2100 or less, do force the date to be in an interval tha male sense for your application
in any case:
Hi, really thanks for your detailed answer. But I still cant it work.. Do I need to add anything else (in script or etc..) for the DateRange validation to work? Currently even I put my expirydate to < today's date, nothing happen (no validation message,
no auto-correct). I could not find the problem.. I will show my code here:
[MetadataType(typeof(FoodMetaData))]
public partial class FOOD
{
[Bind(Exclude = "FoodID")]
public class FoodMetaData
{
[ScaffoldColumn(false)]
public int FoodID { get; set; }
[DateRange(DynamicMinimum="Today", ErrorMessage="Test")]
[DateRange(DynamicMinimum="StorageDate", ErrorMessage="Test storage date")]
public DateTime ExpiryDate { get; set; }
}
[MileStone]
public DateTime Today
{
get { return DateTime.Now; }
}
}
The Form:
@using (Html.BeginForm("CreateFood", "Stock", FormMethod.Post, new { id = "formData" }))
{
@Html.ValidationSummary(false, "Opps. Please correct the mistakes")
<div class="editor-label">
Expiry Date
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ExpiryDate, new { @class = "expirydate" })
@Html.ValidationMessageFor(model => model.ExpiryDate)
</div>
}
Validation for other field do works, just for date i get nothing.. Please help... Really appreciate it....
2) For everything to work properly you have to install the Mvc Controls Toolkit since it has custom Validation and Metadata provider. It is available throught Nuget (Mvc3ControlsToolkit or Mvc2ControlsToolkit), or you can install it manually as explained
here: http://mvccontrolstoolkit.codeplex.com/wikipage?title=Installation
Hi, I did install it.. but I still cant get any validation message.. is it a must to use Html.DateTimeFor for the validation to work? If yes, do you have any idea how to assign a class to Html.DateTimeFor helper like what I did for the EditorFor?
In my previous post I have not noticed you use editorFor....It is not compulsory to use DateTimeFor...but you can't use editorfor on the single datetime value for the reasons I explain below. In any case I strongly suggest to use DateTimeFor...it offers
you more options. DateTimeFor returns an object you can use to render separately the date part and the time part. You can style both with separate css.
The date part can be rendered with three dropdowns(Date method) or with a jQuery picker(DateCalendar method). Both methods have an html attributes dictionary new Dictionary<object, string> {{"class", "expirydate"}}.
However if you use the jquery picker the html attributes will apply just to the textbox the DatePicker will be attached to. To style the picker you have to customiza a jQuery UI css file
Now I can explain why the editorfor cannot be used: the point is that bot fields that need to be compared need to be in the same model, otherwise there is no way for the mvc engine to read the value to compare. This means both the field Today and ExpiryDate
MUST be in the same model because the value of Today must be read and inserted in the validationattributes of ExpiryDate....Now if you use EditorFor on the single ExpiryDate property behind the scene Mvc creates a new model containing just this field ExpiryDate
and pass it to a new View....so it is impossible to read the value of Today from there :) THERE IS NO WAY TO OVERCOME THIS LIMIT, that apply to all conditional validation attributes, since it depends on how the core data structure of the Mvc engine were designed.
However the constraint on Storagedate should work, because it is resolved on the client side, since the Storagedate filed is rendered in the View (at least I have understood ...this way)
yenni104
Member
363 Points
183 Posts
Custom DateTime Validation for MVC 3 unobtrusive client side validation
Oct 18, 2011 07:45 AM|LINK
Hi, I am using MVC 3 unobtrusive client side validation and I need to implement some custom validation rules for my DateTime field.
I got ExpiryDate and Storagedate, where Expirydate should be later or equal to today's date. Also, the Expirydate should not be earlier than the StorageDate.
However, I got no idea how to implement the custom validation. I got the partial class to customize the validation in my Model like this:
[MetadataType(typeof(FoodMetaData))] public partial class FOOD { [Bind(Exclude = "FoodID")] public class FoodMetaData { [ScaffoldColumn(false)] public int FoodID { get; set; } [Required(AllowEmptyStrings = false, ErrorMessage = "Please enter a name")] public object FoodName { get; set; } public object StorageDate { get; set; } public object ExpiryDate { get; set; } } }Any idea how can I declare a custom validation for the DateTime field?? I googled a lot but still no able to find similar solution... Please help...
francesco ab...
All-Star
20954 Points
3286 Posts
Re: Custom DateTime Validation for MVC 3 unobtrusive client side validation
Oct 18, 2011 08:49 AM|LINK
Use the DateTimeInput and the DateRangeAttribute of my Mvc Controls Toolkit. You can define both the previous constraint, on the client side and on the server side, easily by placing two DateRange attributes on the ExpiryDate each for each constraint and by adding a new property called ToDay to your ViewModel (it has just a get returning today). User would not be able to enter a date is nort allowed at all. You have also the option, when the user choose a storageDate, to change expiryDate automatically to make the constraint holds instead of limiting the value of ExpiryDate.
The example application here show an example of use. Other examples of the use of the DateTimeInput are...pratically in almost all tutorials.
Mvc Controls Toolkit | Data Moving Plug-in Videos
yenni104
Member
363 Points
183 Posts
Re: Custom DateTime Validation for MVC 3 unobtrusive client side validation
Oct 18, 2011 09:32 AM|LINK
Hi, can you give me some example??
Because I need something like [DateRange(SMaximum = "2012-1-1", SMinimum = "2008-1-1")] but if for ExpiryDate, i only need the minimum part which is Today's date && StorageDate. I not really understand how to do this since there is no example available there..
Sorry and thanks for your kind help..
francesco ab...
All-Star
20954 Points
3286 Posts
Re: Custom DateTime Validation for MVC 3 unobtrusive client side validation
Oct 18, 2011 01:04 PM|LINK
There are examples....you have to see the ViewModel used in the page of the software distribution. Anyway:
1) define a property you call Today (for example):
[Milestone]
public DateTime Today {
get{
return DateTime.Now;
}
}
please notoce the milestone attribute, this inform the engine that the proprty will not be renderedi in the page;
now you write:
[DateTange(DynamicMinimum='Today')]
[DateTange(DynamicMinimum='StorageDate')]
public DateTime ExpiryDate{get; set;}
This way when user will introduce a wrong date the date will be automatically corrected to match the constraint.
if you use [DateTange(DynamicMinimum='StorageDate', RangeAction = RangeAction.Propagate)]
instead when user will introduce e data that is smaller than ExpiryDate ExpiriDate will be decreased in the Html page to keep the constraint valid.
Th minimum you have define are called Dinamic because they depends on the value of other properties. I suggest to addr also some fixed minimum and fixed maximum, say 1900 and 2100 or less, do force the date to be in an interval tha male sense for your application in any case:
[DateTange(DynamicMinimum='StorageDate', SMaximum = "2000-1-1", SMinimum = "2100-1-1")]
You can add as many date range attribute you like to the same property.
Mvc Controls Toolkit | Data Moving Plug-in Videos
yenni104
Member
363 Points
183 Posts
Re: Custom DateTime Validation for MVC 3 unobtrusive client side validation
Oct 18, 2011 11:01 PM|LINK
Hi, really thanks for your detailed answer. But I still cant it work.. Do I need to add anything else (in script or etc..) for the DateRange validation to work? Currently even I put my expirydate to < today's date, nothing happen (no validation message, no auto-correct). I could not find the problem.. I will show my code here:
[MetadataType(typeof(FoodMetaData))] public partial class FOOD { [Bind(Exclude = "FoodID")] public class FoodMetaData { [ScaffoldColumn(false)] public int FoodID { get; set; } [DateRange(DynamicMinimum="Today", ErrorMessage="Test")] [DateRange(DynamicMinimum="StorageDate", ErrorMessage="Test storage date")] public DateTime ExpiryDate { get; set; } } [MileStone] public DateTime Today { get { return DateTime.Now; } } }The Form:
@using (Html.BeginForm("CreateFood", "Stock", FormMethod.Post, new { id = "formData" })) { @Html.ValidationSummary(false, "Opps. Please correct the mistakes") <div class="editor-label"> Expiry Date </div> <div class="editor-field"> @Html.EditorFor(model => model.ExpiryDate, new { @class = "expirydate" }) @Html.ValidationMessageFor(model => model.ExpiryDate) </div> }Validation for other field do works, just for date i get nothing.. Please help... Really appreciate it....
francesco ab...
All-Star
20954 Points
3286 Posts
Re: Custom DateTime Validation for MVC 3 unobtrusive client side validation
Oct 19, 2011 07:21 AM|LINK
1) The autorrect behaviour happens just if you use the DateTimeInput of the Mvc Controls Toolkit: http://mvccontrolstoolkit.codeplex.com/wikipage?title=DateTimeInput%20and%20DateRange%20attribute otherwise, normal unobtrusive validation is performed and when the field is invalid the usual validation message is shown.
2) For everything to work properly you have to install the Mvc Controls Toolkit since it has custom Validation and Metadata provider. It is available throught Nuget (Mvc3ControlsToolkit or Mvc2ControlsToolkit), or you can install it manually as explained here: http://mvccontrolstoolkit.codeplex.com/wikipage?title=Installation
Mvc Controls Toolkit | Data Moving Plug-in Videos
yenni104
Member
363 Points
183 Posts
Re: Custom DateTime Validation for MVC 3 unobtrusive client side validation
Oct 19, 2011 07:32 AM|LINK
Hi, I did install it.. but I still cant get any validation message.. is it a must to use Html.DateTimeFor for the validation to work? If yes, do you have any idea how to assign a class to Html.DateTimeFor helper like what I did for the EditorFor?
<div class="editor-field">
@Html.EditorFor(model => model.ExpiryDate, new { @class = "expirydate" })
@Html.ValidationMessageFor(model => model.ExpiryDate)
</div>
And is it any additional steps needed because I am using a datepicker?
Really thanks for your help....
francesco ab...
All-Star
20954 Points
3286 Posts
Re: Custom DateTime Validation for MVC 3 unobtrusive client side validation
Oct 19, 2011 09:39 AM|LINK
In my previous post I have not noticed you use editorFor....It is not compulsory to use DateTimeFor...but you can't use editorfor on the single datetime value for the reasons I explain below. In any case I strongly suggest to use DateTimeFor...it offers you more options. DateTimeFor returns an object you can use to render separately the date part and the time part. You can style both with separate css.
The date part can be rendered with three dropdowns(Date method) or with a jQuery picker(DateCalendar method). Both methods have an html attributes dictionary new Dictionary<object, string> {{"class", "expirydate"}}.
However if you use the jquery picker the html attributes will apply just to the textbox the DatePicker will be attached to. To style the picker you have to customiza a jQuery UI css file
Now I can explain why the editorfor cannot be used: the point is that bot fields that need to be compared need to be in the same model, otherwise there is no way for the mvc engine to read the value to compare. This means both the field Today and ExpiryDate MUST be in the same model because the value of Today must be read and inserted in the validationattributes of ExpiryDate....Now if you use EditorFor on the single ExpiryDate property behind the scene Mvc creates a new model containing just this field ExpiryDate and pass it to a new View....so it is impossible to read the value of Today from there :) THERE IS NO WAY TO OVERCOME THIS LIMIT, that apply to all conditional validation attributes, since it depends on how the core data structure of the Mvc engine were designed.
However the constraint on Storagedate should work, because it is resolved on the client side, since the Storagedate filed is rendered in the View (at least I have understood ...this way)
Mvc Controls Toolkit | Data Moving Plug-in Videos
yenni104
Member
363 Points
183 Posts
Re: Custom DateTime Validation for MVC 3 unobtrusive client side validation
Oct 19, 2011 10:02 AM|LINK
Hi, sorry but i dont really understand how to change the editorfor to datetimefor...
francesco ab...
All-Star
20954 Points
3286 Posts
Re: Custom DateTime Validation for MVC 3 unobtrusive client side validation
Oct 19, 2011 03:35 PM|LINK
See the example of use of the DateTimeFor here: BinariesWithSimpleExamples
Basically:
@{var DT = DateTimeFor(m => m.ExpiryDate, dateInCalendar : true)}
containerHtmlAttributes: new Dictionary<string, object> {{"class", "expirydate"}})Mvc Controls Toolkit | Data Moving Plug-in Videos