ErrorMessage is ignored in DataAnnotations DataType Attribute
I have a Model that is using DataAnnotations. Something like
public class Appointment {
[Required(ErrorMessage="Please enter your name")]
public string Name { get; set; }
[Required(ErrorMessage="Please enter your appointment date?")]
[DataType(DataType.Date, ErrorMessage="Appointment date is not a date")]
public DateTime AppointmentDate { get; set; }
}
The "Required" attributes respect the value in ErrorMessage; that is, if I don't enter a value, I am getting my "please enter" message. However, if I enter a string in the DateTime field, I am getting a standard system error message "The value 'blah' is not valid for AppointmentDate".
I debugged through ASP.NET MVC code, and it seems t开发者_如何学JAVAhat in the case of FormatException it doesn't pick the right display name from propertyMetadata. Either that, or I am missing something blatantly obvious :/
Did anybody run into this problem? Is it me, or is it just beta (I am using ASP.NET MVC 2 Beta)?
In MVC1 DataType attribute does not do what you'd expect, it looks like it does not in MVC2 either. Your best call is to have a string property representing the date, check it's validity there.
Here's a small excerpt from a project (using DataAnnotations and xVal):
private List<ErrorInfo> _errors;
private List<ErrorInfo> Errors
{
get
{
if (_errors == null)
_errors = new List<ErrorInfo>();
return _errors;
}
//set { _errors = value; }
}
private string _startDateTimeString;
/// <summary>
/// A string reprsentation of the StartDateTime, used for validation purposes in the views.
/// </summary>
/// <remarks>
/// If the user passes something like 45/45/80 it would be a valid mm/dd/yy format, but an invalid date,
/// which would cause an InvalidOperationException to be thrown by UpdateModel(). By assigning dates to string properties
/// we can check not only the format, but the actual validity of dates.
/// </remarks>
public string StartDateTimeString
{
get
{
return _startDateTimeString;
}
set
{
// Check whether the start date passed from the controller is a valid date.
DateTime startDateTime;
bool validStartDate = DateTime.TryParse(value, out startDateTime);
if (validStartDate)
{
StartDateTime = startDateTime;
}
else
{
Errors.Add(new ErrorInfo("StartDateTime", "Provide a valid date for the start time."));
}
_startDateTimeString = value;
}
}
partial void OnValidate(ChangeAction action)
{
if (action != ChangeAction.Delete)
{
Errors.AddRange(DataAnnotationsValidationRunner.GetErrors(this));
if (StartDateTimeString != null)
{
DateTime startDateTime;
if (!DateTime.TryParse(StartDateTimeString, out startDateTime))
{
Errors.Add(new ErrorInfo("StartDateTime", "Provide a valid date for the start time."));
}
}
if (Errors.Any())
throw new RulesException(Errors);
}
}
}
It makes sense to have the check in both places in our project, but I just want to show you a concept.
I ran into this problem today and I wanted to share another workaround...
[Required(ErrorMessage="Please enter your appointment date?")]
//[DataType(DataType.Date, ErrorMessage="Appointment date is not a date")]
[Range(typeof(DateTime), "1/1/1880", "1/1/2200", ErrorMessage = "...")]
public string AppointmentDate { get; set; }
You will need to adjust your code to work with a string instead of a datetime (presumably easy if this is part of your view model), but the error message works as expected and the string is guaranteed to be a valid date (possibly with a time).
精彩评论