Custom DateTime Validation for MVC 3 unobtrusive client side validationhttp://forums.asp.net/t/1731351.aspx/1?Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationMon, 24 Oct 2011 02:54:34 -040017313514643122http://forums.asp.net/p/1731351/4643122.aspx/1?Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationCustom DateTime Validation for MVC 3 unobtrusive client side validation <p>Hi, I am using MVC 3 unobtrusive client side validation and I need to implement some custom validation rules for my DateTime field.</p> <p>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.</p> <p>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:</p> <pre class="prettyprint">[MetadataType(typeof(FoodMetaData))] public partial class FOOD { [Bind(Exclude = &quot;FoodID&quot;)] public class FoodMetaData { [ScaffoldColumn(false)] public int FoodID { get; set; } [Required(AllowEmptyStrings = false, ErrorMessage = &quot;Please enter a name&quot;)] public object FoodName { get; set; } public object StorageDate { get; set; } public object ExpiryDate { get; set; } } }</pre> <p>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...</p> 2011-10-18T07:45:41-04:004643215http://forums.asp.net/p/1731351/4643215.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>Use the <a href="http://mvccontrolstoolkit.codeplex.com/wikipage?title=DateTimeInput%20and%20DateRange%20attribute"> DateTimeInput</a> and the <a href="http://mvccontrolstoolkit.codeplex.com/wikipage?title=Data%20Annotations"> DateRangeAttribute </a>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.</p> <p>The example application <a href="BinariesWithSimpleExamples">here</a> show an example of use. Other examples of the use of the DateTimeInput are...pratically in almost all tutorials.</p> 2011-10-18T08:49:45-04:004643285http://forums.asp.net/p/1731351/4643285.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>Hi, can you give me some example??</p> <p>Because I need something like [DateRange(SMaximum = <span style="color:#a31515"> &quot;2012-1-1&quot;</span>, SMinimum = <span style="color:#a31515">&quot;2008-1-1&quot;</span>)] but if for ExpiryDate, i only need the minimum part which is Today's date &amp;&amp; StorageDate. I not really understand how to do this since there is no example available there..</p> <p>Sorry and thanks for your kind help..</p> 2011-10-18T09:32:45-04:004643737http://forums.asp.net/p/1731351/4643737.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>There are examples....you have to see the ViewModel used in the page of the software distribution. Anyway:</p> <p>1) define a property you call Today (for example):</p> <p>[Milestone]</p> <p>public DateTime Today {</p> <p>get{</p> <p>return DateTime.Now;</p> <p>}</p> <p>}</p> <p>please notoce the milestone attribute, this inform the engine that the proprty will not be renderedi in the page;</p> <p></p> <p>now you write:</p> <p>[DateTange(DynamicMinimum='Today')]</p> <p>[DateTange(DynamicMinimum='StorageDate')]</p> <p>public DateTime ExpiryDate{get; set;}</p> <p></p> <p>This way when user will introduce a wrong date the date will be automatically corrected to match the constraint.</p> <p></p> <p>if you use&nbsp;[DateTange(DynamicMinimum='StorageDate', RangeAction = RangeAction.Propagate)]</p> <p>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.</p> <p></p> <p>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:</p> <p>[DateTange(DynamicMinimum='StorageDate', SMaximum = &quot;2000-1-1&quot;, SMinimum = &quot;2100-1-1&quot;)]</p> <p>You can add as many date range attribute you like to the same property.</p> 2011-10-18T13:04:07-04:004644496http://forums.asp.net/p/1731351/4644496.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>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 &lt; today's date, nothing happen (no validation message, no auto-correct). I could not find the problem.. I will show my code here:</p> <pre class="prettyprint">[MetadataType(typeof(FoodMetaData))] public partial class FOOD { [Bind(Exclude = &quot;FoodID&quot;)] public class FoodMetaData { [ScaffoldColumn(false)] public int FoodID { get; set; } [DateRange(DynamicMinimum=&quot;Today&quot;, ErrorMessage=&quot;Test&quot;)] [DateRange(DynamicMinimum=&quot;StorageDate&quot;, ErrorMessage=&quot;Test storage date&quot;)] public DateTime ExpiryDate { get; set; } } [MileStone] public DateTime Today { get { return DateTime.Now; } } }</pre> <p>The Form:</p> <pre class="prettyprint">@using (Html.BeginForm("CreateFood", "Stock", FormMethod.Post, new { id = "formData" })) { @Html.ValidationSummary(false, "Opps. Please correct the mistakes") &lt;div class="editor-label"&gt; Expiry Date &lt;/div&gt; &lt;div class="editor-field"&gt; @Html.EditorFor(model =&gt; model.ExpiryDate, new { @class = "expirydate" }) @Html.ValidationMessageFor(model =&gt; model.ExpiryDate) &lt;/div&gt; }</pre> <p>Validation for other field do works, just for date i get nothing.. Please help... Really appreciate it....</p> 2011-10-18T23:01:42-04:004644892http://forums.asp.net/p/1731351/4644892.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>1) The autorrect behaviour happens just if you use the DateTimeInput of the Mvc Controls Toolkit:&nbsp;<a href="http://mvccontrolstoolkit.codeplex.com/wikipage?title=DateTimeInput%20and%20DateRange%20attribute">http://mvccontrolstoolkit.codeplex.com/wikipage?title=DateTimeInput%20and%20DateRange%20attribute</a>&nbsp;otherwise, normal unobtrusive validation is performed and when the field is invalid the usual validation message is shown.</p> <p>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:&nbsp;<a href="http://mvccontrolstoolkit.codeplex.com/wikipage?title=Installation">http://mvccontrolstoolkit.codeplex.com/wikipage?title=Installation</a></p> <p><a href="http://mvccontrolstoolkit.codeplex.com/wikipage?title=DateTimeInput%20and%20DateRange%20attribute"></a></p> 2011-10-19T07:21:45-04:004644914http://forums.asp.net/p/1731351/4644914.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>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?</p> <p>&lt;div class=&quot;editor-field&quot;&gt;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Html.EditorFor(model =&gt; model.ExpiryDate, new { @class = &quot;expirydate&quot; })<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Html.ValidationMessageFor(model =&gt; model.ExpiryDate)<br> &nbsp;&nbsp;&nbsp; &lt;/div&gt;</p> <p>And is it any additional steps needed because I am using a datepicker?</p> <p>Really thanks for your help....</p> <p></p> 2011-10-19T07:32:39-04:004645109http://forums.asp.net/p/1731351/4645109.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>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.&nbsp;</p> <p></p> <p>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&lt;object, string&gt; {{&quot;class&quot;, &quot;expirydate&quot;}}.</p> <p>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</p> <p></p> <p>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 :)&nbsp;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.</p> <p></p> <p>However the constraint on Storagedate&nbsp;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)</p> 2011-10-19T09:39:22-04:004645160http://forums.asp.net/p/1731351/4645160.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>Hi, sorry but i dont really understand how to change the editorfor to datetimefor...</p> 2011-10-19T10:02:58-04:004645723http://forums.asp.net/p/1731351/4645723.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>See the example of use of the DateTimeFor here:&nbsp;<a class="FileNameLink" href="http://mvccontrolstoolkit.codeplex.com/releases/view/74521#DownloadId=289609" id="fileDownload0" tabindex="9">BinariesWithSimpleExamples</a>&nbsp;</p> <p>Basically:</p> <p></p> <p>@{var DT = DateTimeFor(m =&gt; m.<span class="Apple-style-span" style="white-space:pre">ExpiryDate, dateInCalendar : true)</span>}</p> <pre>@DT.DateCalendar(<br> inLine: false,<br> calendarOptions: new CalendarOptions<br> {<br> ChangeYear=true,<br> ChangeMonth=true,<br> <br> },</pre> <pre>containerHtmlAttributes: new Dictionary&lt;string, object&gt; {{&quot;class&quot;, &quot;expirydate&quot;}})</pre> <pre></pre> <pre>There are various calendar option you can choose....I put the ones I like more</pre> <pre>I have chosen to use the jQuery picker, so you have to include the relateive js files, and css</pre> 2011-10-19T15:35:53-04:004646219http://forums.asp.net/p/1731351/4646219.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>HI, thank you so much but i didnt work.. i get compilation error...</p> 2011-10-19T23:18:01-04:004646228http://forums.asp.net/p/1731351/4646228.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>Sorry I have written that code directly in the post without compiling it..and in a hurry...so I forgot the Html before the DateTimeFor and a ;</p> <p></p> <p>This should work:</p> <p></p> <p>@{var DT = Html.DateTimeFor(m =&gt; m.ExpiryDate, dateInCalendar : true);}</p> <pre>@DT.DateCalendar(<br> inLine: false,<br> calendarOptions: new CalendarOptions<br> {<br> ChangeYear=true,<br> ChangeMonth=true,<br> <br> },</pre> <pre>containerHtmlAttributes: new Dictionary&lt;string, object&gt; {{&quot;class&quot;, &quot;expirydate&quot;}})</pre> 2011-10-19T23:28:57-04:004646234http://forums.asp.net/p/1731351/4646234.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>Hi, i get &quot;Value cannot be null&quot; instead...</p> 2011-10-19T23:35:09-04:004646579http://forums.asp.net/p/1731351/4646579.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>The point is that you showed me just the MetaDataType...so I don't know too much of your model. Does your ExpiryDate is a DateTime? ie a nullable DateTime ?</p> <p>In such a case you have to furnish a default date to be used as initial date when the Date is null as shown below:</p> <p></p> <p>@{var DT = Html.DateTimeFor(m =&gt; m.ExpiryDate, dateInCalendar : true, emptyDate: DateTime.Now);}</p> <p></p> <p>Obviously you can set emptyDate to whatever you like not necessaruly to&nbsp;DateTime.Now.</p> <p>Don't forget to include also the js and css files needed by the jQuery datepicker. Finally, either you render the StorageDate in yiour page with a DateTimeInput, or apply to it the Milestone attribute as you have done with the Today property.&nbsp;</p> 2011-10-20T06:59:54-04:004648035http://forums.asp.net/p/1731351/4648035.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>HI, really thanks for your help. But both of my date field is not nullable type. ALso, there is nth wrong with the datepicker.. I just simply cant make the validation work..</p> 2011-10-20T23:43:16-04:004648614http://forums.asp.net/p/1731351/4648614.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>Pls motice, you will see no error message, but the user will simply unable to insert a wrong date, because any wrong date will be ccorrected to be withing the constraints.&nbsp;</p> <p>Pls prepare a selfcontained example with no db and send it to me through the contact form of my blog(it has the option to attach files).</p> 2011-10-21T07:27:59-04:004650857http://forums.asp.net/p/1731351/4650857.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>Hi yenni</p> <p>You can write the code as follow:</p> <pre class="prettyprint">public sealed class ExpiryDateAttribute : ValidationAttribute { public override bool IsValid(object value) { DateTime expiryDate = (DateTime)value; return (expiryDate &gt;= DateTime.Now); } } public sealed class StoragedateAttribute : ValidationAttribute { public string expiryDateProperty { get; set; } public override bool IsValid(object value) { string expiryDateString = HttpContext.Current.Request[expiryDateProperty]; DateTime storagedate = (DateTime)value; DateTime expiryDate = DateTime.Parse(expiryDateString); return expiryDate &lt; storagedate; } }</pre> <p>And in your view model:</p> <pre class="prettyprint">[ExpiryDate] public DateTime ExpiryDate { get; set; } [Storagedate(expiryDateProperty = "ExpiryDate")] public DateTime Storagedate { get; set; } </pre> <p>Hope this helpful</p> <p>Regards</p> <p>Young Yang</p> 2011-10-23T12:48:28-04:004650863http://forums.asp.net/p/1731351/4650863.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>Hi, amazingly it works! Really thanks a lot for your help...<br> I got one more question, do you have any idea how I can validate both the datefield to ensure it is a valid Datetime in a specific format? Because even with the datepicker, user can input any string/numbers in the textfield and click submit.. so I want to validate those manually entered value to ensure it is a DateTime which match the format of my datepicker's Date declared as:</p> <pre class="prettyprint">$('#expirydate').datepicker({ constrainInput: true, minDate: 0, dateFormat: 'D, dd M yy' });</pre> <p>And one of the datetime form field with the format:</p> <pre class="prettyprint">&lt;div class="editor-label"&gt; Expiry Date &lt;/div&gt; &lt;div class="editor-field"&gt; @Html.TextBox("ExpiryDate", String.Format("{0:ddd, d MMM yyyy}", DateTime.Now), new { id = "expirydate" }) @Html.ValidationMessageFor(model =&gt; model.ExpiryDate) &lt;/div&gt;</pre> <p>Really thanks a lot for your help!</p> 2011-10-23T13:06:41-04:004651198http://forums.asp.net/p/1731351/4651198.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>Hi yenni,</p> <p>You just need to add a regularexpression attribute in your model, you can do it like this:</p> <pre class="prettyprint">[ExpiryDate] [RegularExpression(@&quot;^(19|20)dd([- /.])(0[1-9]|1[012])2(0[1-9]|[12][0-9]|3[01])$)] public DateTime ExpiryDate { get; set; }</pre> <p>You can&nbsp;change the expression to what you want.</p> <p>Hope this helpful</p> <p>Regards</p> <p>Young Yang</p> 2011-10-24T01:26:31-04:004651252http://forums.asp.net/p/1731351/4651252.aspx/1?Re+Custom+DateTime+Validation+for+MVC+3+unobtrusive+client+side+validationRe: Custom DateTime Validation for MVC 3 unobtrusive client side validation <p>HI, Thanks!! But <span class="comment-copy">I cant find any regex which validate date in the format of Mon, 31 Oct 2011 (datepicker format: 'D, dd M yy'), any idea??<br> <br> Really thanks a lot...<br> </span></p> 2011-10-24T02:40:07-04:00