DataAnnotations Date Range - asp.net-mvc

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/

Related

should I remover all [DataType(DataType.Date)] from my models?

I was having a problem where two fields "BattleStartDate" and "BattleEndDate" where not displaying on my edit form, even though the correct vales had been set on the DB when the record was created. The Create and Edit views both use a common partial View _BattleEditFields.
My old model:
[DisplayName("Battle Start Date")]
[Required(ErrorMessage = "Enter date (mm/dd/yyy) when the battle started")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[DataValidation(ValidationType.RangeValidation, "The battle starting date must be after 1/1/1860 and before 6/1/1865.")]
public DateTime BattleStartDate { get; set; }
[DisplayName("Battle End Date")]
[Required(ErrorMessage = "Enter date (mm/dd/yyy) when the battle ended")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[DataValidation(ValidationType.RangeValidation, "The battle ending date must be after 1/1/1860 and before 6/1/1865.")]
[DataValidation(ValidationType.CompareDates, "The battle ending date must be equal to or greater than the start date.", compareWith: "BattleStartDate")]
public DateTime BattleEndDate { get; set; }
I noticed that at runtime I got the following error message.
error CS0103: The name 'type' does not exist in the current contex
Once I updated the model to removed the [DataType(DataType.Date)] from both fields, every thing worked fine. I have several other date fields that also have [DataType(DataType.Date)] in the model (see below). Should I just go ahead and remove all of them, even though it does not appear to be causing a problem?? (just have to go back an test the change).
-- these are audit type fields and not displayed to the user --
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime BattleDateAccepted { get; set; }
// --------------------------------------------------------------------------------------------
public string BattleChangedBy { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime BattleDateChange { get; set; }
Normally we would advise against this, but it is advised that you try to follow conventions and patterns in your code, so seeing some Date properties with this attribute and not others can easily lead to confusion, some developers down the track might add it back to those that are missing, other devs might remove it from all of them as you are suggesting here. So this becomes a depends kind of scenario...
Firstly identify why you are using the DataType(DataType.Date) attribute in the first place, in MVC the first reason is usually for validation, however this attribute can also be used in DB ORM libraries that manage your database schema like Entity Framework to ensure that the type of the field in the database should be a Date ONLY data type.
EF has other attributes that can be used for the same purpose, in MVC apps it is common to use a convention to map this attribute to reduce the risk of the two attributes being set with conflicting values.
If you are using an ORM that needs this attribute to manage the database schema, then each of these attributes that you remove may need a corresponding change set elsewhere in your model to ensure that the DB schema is not affected.
This attribute is heavily referenced in MVC validation documentation and is a the minimal configuration for Date input validation. Removing this attribute from the model might still allow invalid values to be accepted through your API, even if the view (due to your other validation attributes) correctly generates the validation in the UI. If your API is not exposed to external callers this may not be a concern to you.
As you have identified that the fields that have this attribute, but are not displayed in the UI do not cause this error you should look into your view code and configuration, to see if you are using a 3rd party control package that is missing a component.
'type' does not exist in the current context is NOT a common error associated with this attribute specifically, but could occur with custom control or UI validation code that references mismatched assemblies, usually a .Net FX UI component in a .Net Core project or vice versa.
In your case, if removing the DataType attribute resolves your error AND has no other adverse effects on your application runtime OR deployment, then remove it. If your model is not exposed through an API to external callers or you would not be letting external callers modify the other fields, then for consistency I would recommend removing this attribute from all the DateTime fields.
Because this is a against the normal MVC expectations for validation, I would include a note about this in your documentation for the model/project so you remember why you have made this decision.
If you have reasons other than validation for keeping the attributes you should investigate further to understand the cause before you apply this to all Date fields in your entire model.

Requiring Date and Time

I need a datetime. I currently have:
Model:
[DisplayFormat(DataFormatString = "{0:f}", ApplyFormatInEditMode = true)]
public DateTime DateFrom { get; set; }
Controller:
assetBookingModel.DateFrom = DateTime.Now.AddDays(1);
View:
#Html.EditorFor(model => model.DateFrom)
This displays a text box with a date and no time. I can add a calendar extender with a time property without too much problems, but MVC doesn't seem to have any proper validation for this, or add in the time by default.
I have searched the web and there isn't too much help to be found.
What is the best way to go about implementing a Date and Time field, that will not accept only the Date.
This is what I'd use, [CustomValidation]. Allows you to create your own validation function. A few useful examples are here:
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.customvalidationattribute%28v=vs.95%29.aspx

Validate Date in MM/dd/YYYY format in mvc

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.

MVC4 validate Date to be today or after?

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.

Date range validation with Entity Framework 4 data annotations

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.

Resources