I have declared a property in MVC info file like
[Required(ErrorMessage = "End Date has not being entered")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[RegularExpression(#"^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/]\d{4}$", ErrorMessage = "End Date should be in MM/dd/yyyy format")]
public DateTime? ExpirationDate { get; set; }
But when I am entered a date in correct format like 5/13/2013. It stills show the errormessage that
End Date should be in MM/dd/yyyy format
What code I am missing or there is any other error with the above.
You can't validate dates with regular expression, use DateTime.TryParseExact to convert the string into a DateTime object. Regex will always miss subtleties such as leap years, etc.
You can't use the Regular expression to validate your DateTime in model, as Regex always validates the string values and when you apply it on DateTime it tries to convert in string. The string actually not in the format of MM/dd/YYYY and always throws the validation error.
Either you can choose one of the following way:
Customize the error message in a resource file
You can create a custom attribute derived from RegularExpressionAttribute and use that instead.
The first part of the regexp does not allow for single digit month. You should change it to
(#"^([0]?\d|[1][0-2])/..."
Note the ? mark which means that the 0 is optional.
Check it out. I tried this not expecting it to work.
You can actually use a RegExp to validate a DateTime in MVC. This is my setup:
RegExp Attribute on property:
[RegularExpression(#"(^$)|(^\d{2}/\d{2}/\d{4})|(^((\d{1})|(\d{2}))/((\d{1})|(\d{2}))/(\d{4})\s((\d{1})|(\d{2}))[:]{1}((\d{1})|(\d{2}))[:]{1}((\d{1})|(\d{2}))\s((AM)|(PM)))", ErrorMessage = "Invalid Date")]
Enforced validation:
Empty String,
1 or 2 digits for month/date in the MM/dd/yyyy format (e.g. 3/20/2015 or 03/20/2015 or 3/2/2015),
C# Date (e.g. MM/dd/yyyy hh:mm:ss tt) - This is what allows ModelState.IsValid to return true for this property once the server converts it to a C# DateTime
TextBoxFor on view:
#Html.TextBoxFor(x => x.DateOfWeightAndHeightCapture, "{0:MM/dd/yyyy}", new { #class = "form-control" })
This lets you have a DateTime property on a model, edited by a MVC TextBoxFor, that enforces client side and server side validation.
Related
I'm having a terrible time adding a date to a view. I want the user to be able to type in a date like 6/30/15 or 6/30/2015, but the validation keeps failing if I use the 2 digit date. I've tried to "tell" MVC to accept a two digit date, but it always fails. Can someone explain how to get this right?
My view is set up like this (including just the troublesome date field for brevity):
#model Models.CompanyContracts
#Html.EditorFor(m => m.BegDate)
I started out with a simple model with a date field defined like this:
public DateTime? BegDate { get; set; }
I got an error saying "The field BegDate must be a date" when I entered the date as 6/30/15 or 06/30/15; I did not get the error when I entered 6/30/2015 or 06/30/2015.
So I tried to add a type and display attribute as describe
Here: Format datetime in asp.net mvc 4
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:M/d/yy}", ApplyFormatInEditMode = true)]
I get the same error trying to enter 6/30/15. I tried several different formats, including a datatype and not a displayformat, including a displayformat and not a datatype, but I get the "The field BegDate must be a date" error everytime.
I tried a regular expression validation and it also failed (both the MVC validation and the regular expression; obviously the regex I got from http://regexlib.com/DisplayPatterns.aspx?cattabindex=4&categoryId=5&AspxAutoDetectCookieSupport=1 needs some work):
[RegularExpression(#"^((0?[13578]|10|12)(-|\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[01]?))(-|\/)((19)([2-9])(\d{1})|(20)([01])(\d{1})|([8901])(\d{1}))|(0?[2469]|11)(-|\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[0]?))(-|\/)((19)([2-9])(\d{1})|(20)([01])(\d{1})|([8901])(\d{1})))$", ErrorMessage = "Invalid Date")]
public DateTime? BegDate { get; set; }
Can someone tell me how to get MVC to accept entering dates with 2 or 4 digits?
One other note, no external date pickers. I need to get this working with a simple entering of text. Once I can prove that can be done, my boss might allow me to spend some time figuring out a date picker. Thanks!
-- Update 7/20/15 --
Anyone have suggestions for this? I haven't found anything online that's helped me. I'd appreciate any feedback at this point to give me somewhere else to look for a solution.
-- Update 7/29/15 --
Still looking for suggestions. Any ideas at all?
I think it's simply not possible without some kind of twist.
How is the engine/code suppose to know which year it is if you enter just 15 as the year.
Is it 2015 ? 1915 ? 2115 ?
You need to pass the 4 digits to create the dates, if you only have 2 digits you cannot create the date.
So in your case what I would try is to default and hide the '20' prefix (assuming you can only enter a date for 2000's) to your 2 digits year input (or add it somehow using a bit a javascript).
In my MVC4 project I have a Meta class where I have my date format specified with DataAnnotations. I want to limit the range to the SQL DateTime type.
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[Range(typeof(DateTime), "01/01/1753", "12/31/9999", ErrorMessage = "Check Date")]
public DateTime SeniorityDate
{
get;
set;
}
The format works fine without the range validation. When I add the range validation and I enter an invalid date I get the error message specified. The issues is when I fix the date again to something like 01/27/2008 then the validator still indicates the date is not valid. I assumed this is because I am not entering nor do I want a time component. Is there a way around this issue?
I ended up modifying code listed here to meet my needs.
http://www.headspringlabs.com/blog/mvc-custom-unobtrusive-validator-attribute-date-range-validation/
I have a playlist Model class in MVC4 that has a Date property, and when a user creates it, I want them not to be able to specify a date before today (so today or after).
Here's part of my Playlist class:
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[Required(ErrorMessage = "Incorrect date format.")]
public DateTime Date { get; set; }
How do I add validation for this "range"? Right now it's only validating to see if it's a valid date, but 11/30/2012 is valid and won't throw up any errors even though it was yesterday.
I'm using Razor for my Views. Thank you.
You can't validate against dynamic values using the Range attribute. You can create your own validator based on ValidationAttribute that validates the date against the current or a calculated date. Or you can use the IValidatableObject interface in your model class (buddy class to stop it getting overwritten by EF), and validate the properties you want there.
I am using Entity Framework 4 to provide the model for a ASP.NET MVC3 / Razor2 web application. I am using DataAnnotations to implement validation. I need to limit some dates to the range accepted by the SQL smalldatetime type.
My problem is that I can't get the RangeAttribute to work correctly for a date field. The model metadata definition for the field in question is:
[Display(ResourceType = typeof(Resources.Patient), Name = "DateOfBirth_Name")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
[Range(typeof(DateTime), "01/01/1900", "06/06/2079", ErrorMessageResourceType = typeof(Resources.Patient), ErrorMessageResourceName = "DateOfBirth_Range")]
public System.DateTime DateOfBirth { get; set; }
With this code, whatever value I put into the date field, it is treated as invalid by the application. In case its' relevant, I am using the JQuery-UI date picker with the field in question as well.
Can anyone help please?
You do not specify where the error occurs, but my guess is that it is client-side(?) jQuery Validation does not work well with the RangeAttribute. To verify, disable jQuery Validation and the valid input should pass the (server) validation.
To get around this you will have to write your own date range validation, e.g. http://blogs.msdn.com/b/stuartleeks/archive/2011/01/25/asp-net-mvc-3-integrating-with-the-jquery-ui-date-picker-and-adding-a-jquery-validate-date-range-validator.aspx
Alternatively you could look into packages such as Data Annotations Extensions or MVC Foolproof Validation to see if they could be used for solving the problem.
In our ASP.NET MVC 4 application, one of the models has a field of the DateTime type. When editing such model objects via a form, the value for the DateTime field has to be non-empty and on the format yyyy-MM-dd H:mm:ss (e.g., 2012-10-17 10:49:00). How do I ensure this field is correctly validated in the application? I've tried the following annotations:
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.DisplayFormat(DataFormatString="yyyy-MM-dd H:mm:ss",
ApplyFormatInEditMode=true)]
However, validation of form data doesn't require all components of the format to be present. For instance, the value '2012-10-17' is accepted (leaving out the 'H:mm:ss' part). It's just verified that the field contains a valid DateTime string.
How should I ensure that this DateTime field is indeed on my specified format (yyyy-MM-dd H:mm:ss)?
Alternative solution - view-only model class
Darin's solution is of course valid, but it's not the only one you can use. And it would require you to write more complex code than with this solution that I'm going to show you here.
So this is an alternative. I'd suggest that instead of creating a custom model binder you rather create a separate view model class that instead of taking DateTime takes a string where you can set as complex validation regular expression as you like. And then have a method on it that would translate it to your application/domain model class instance (and back).
// suppose this app model
public class User
{
[Required]
public string Name { get; set; }
[Required]
public DateTime DateOfBirth { get; set; }
}
public class ViewUser
{
[Required]
public string Name { get; set; }
[Required]
[RegularExpression("\d{4}-\d{2}-\d{2}(?:\s\d{1,2}:\d{2}:\d{2})?")]
public string DateOfBirth { get; set; }
public ViewUser(User user)
{
this.Name = user.Name;
this.DateOfBirth = user.DateOfBirth.ToString("yyyy-MM-dd H:mm:ss");
}
public User ToPoco()
{
return new User {
Name = this.Name,
DateOfBirth = DateTime.Parse(this.DateOfBirth, "yyyy-MM-dd H:mm:ss")
};
}
}
With a bit of tweaking you could inherit ViewUser from User class and use new keyword on DateOfBirth and use base property to store correct typed value. In that case you wouldn't need the ToPoco method.
Note: you will have to use DateTime.TryParseExact method to parse your dates because they may include time or they may not. I didn't include that in my code because it depends on the exact requirements of your date input.
You could write a custom model binder which will use the exact format you have specified in the DisplayFormat attribute. I have shown an example of how this could be achieved in this post.
Also don't be confused into thinking that the DisplayFormat attribute overrides the Required attribute. The DisplayFormat is only used for displaying the field in the input field. It is not a validation attribute. It has strictly nothing to do with validation and when the form is POSTed to the server it is never used.