ASP.NET MVC 2 "значение" в переопределении IsValid в переданном атрибуте DataAnnotation равно нулю, когда отправляется неверная дата
Это мой первый вопрос о переполнении стека. Мне нужна помощь по проблеме, с которой я столкнулся во время проекта ASP.NET MVC2, над которым я сейчас работаю. Я должен отметить, что я относительно новичок в дизайне MVC, поэтому, пожалуйста, несите мое невежество. Здесь идет: у меня есть обычная форма, на которой показаны различные детали о человеке. Одним из них является "Дата рождения". Мой взгляд такой
<div class="form-items">
<%: Html.Label("DateOfBirth", "Date of Birth:") %>
<%: Html.EditorFor(m => m.DateOfBirth) %>
<%: Html.ValidationMessageFor(m => m.DateOfBirth) %>
</div>
Я использую шаблон редактора, который нашел, чтобы правильно показывать только дату:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>"%>
<%= Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty))%>
Я использовал LinqToSql конструктор, чтобы создать свою модель из базы данных SQL. Чтобы выполнить некоторую проверку, я создал частичный класс Person для расширения класса, созданного дизайнером (в том же пространстве имен):
[MetadataType(typeof(IPerson))]
public partial class Person : IPerson
{ //To create buddy class }
public interface IPerson
{
[Required(ErrorMessage="Please enter a name")]
string Name { get; set; }
[Required(ErrorMessage="Please enter a surname")]
string Surname { get; set; }
[Birthday]
DateTime? DateOfBirth { get; set; }
[Email(ErrorMessage="Please enter a valid email")]
string Email { get; set; }
}
Я хочу убедиться, что введена правильная дата. Поэтому я создал собственный атрибут DataAnnotation для проверки даты:
public class BirthdayAttribute : ValidationAttribute
{
private const string _errorMessage = "Please enter a valid date";
public BirthdayAttribute() : base(_errorMessage) { }
public override bool IsValid(object value)
{
if (value == null)
{
return true;
}
DateTime temp;
bool result = DateTime.TryParse(value.ToString(), out temp);
return result;
}
}
Ну, моя проблема заключается в следующем. Как только я введу неправильную дату в поле DateOfBirth, пользовательское сообщение не будет отображаться, даже если используется такой атрибут, как [Birthday(ErrorMessage=".....")]. Отображаемое сообщение - это сообщение, возвращенное из БД, т. Е. "Значение" 32/4/1967 "недопустимо для DateOfBirth". Я попытался ввести некоторые точки останова вокруг кода и обнаружил, что "значение" в атрибуте всегда равно нулю, когда дата неверна, но всегда получает значение, если дата в правильном формате. То же самое (значение == null) также передается в коде, сгенерированном дизайнером.
Эта вещь сводит меня с ума. Кто-нибудь может помочь мне разобраться с этим? Также, если кто-то может сказать мне, где именно находится точка входа из представления в базу данных. Это связано с моделью связующего? потому что я хотел точно проверить, какое значение передается, когда я нажимаю кнопку "отправить". Спасибо.
1 ответ
Вообще говоря, все средства проверки - это работа после значений, связанных связующим. Как вы понимаете, невозможно связать значение dateTime со строкой, такой как "asdvfvk". Поэтому, когда связыватель сталкивается с такой ошибкой, он добавляет ее в ModelState (взгляните на ModelState["DateOfBirth"].Errors[0].ErrorMessage) и связывает значение по умолчанию. Значение по умолчанию для DateTime? имеет значение null, поэтому вы всегда получаете его в методе IsValid. Это нормально. Так что вы можете видеть, что проверка даты имеет смысл, если вы хотите проверить, например, больше ли она, чем какая-либо другая дата. Если входная строка неверна, дальнейшая проверка не имеет смысла.
Что ты можешь сделать?
Первый простой способ - вы можете исправить свои действия следующим образом
[HttpPost]
public ActionResult About(Person person, string dateOfBirth) {
var birthdayAttribute = new BirthdayAttribute();
if( !birthdayAttribute.IsValid(dateOfBirth)) {
ModelState["DateOfBirth"].Errors.Clear();
ModelState.AddModelError("DateOfBirth", birthdayAttribute.ErrorMessage);
}
.......
}
Как видите, есть строка dateOfBirth, поэтому у связывателя нет проблем с привязкой строкового значения. Но это не сделает ваших пользователей счастливыми.
Лучший способ - убедиться, что строка будет в правильном формате с клиентским Javascript. На самом деле люди используют средства выбора даты для дат и чувствуют себя хорошо.
Кроме того, посмотрите здесь http://forums.asp.net/t/1512140.aspx Ответ Especialy Брэда Уилсона.