Requiring Date and Time - asp.net-mvc

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

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.

DataAnnotations Date Range

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/

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.

How can I reformat the way a data appears inside an ASP MVC Razor page?

I have the following code:
<li>Reviewed: #Model.Modified</li>
and a model that looks like this:
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime? Modified { get; set; }
However when displayed then the date appears as follows:
REVIEWED: 8/1/2012 2:42:34 PM
Is there a simple way that I could change the way the date
displays so it appears as just 8/1/2012 2PM ?
You can use DateTime.ToString(format) in your view as well, to format the date the way you want.
So in your case, something like:
#Model.Modified.ToString("dd/MM/yyyy htt")
You can use DisplayExtensions.DisplayFor method:
#Html.DisplayFor(model => model.Modified)
This helper works with data annotations and display templates.
Try this
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy htt}")]
public DateTime? Modified { get; set; }
This website provides easy to understand information on setting date/time formats
Date Formatting C#

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