Сбой проверки модели ASP.NET MVC2 с использованием формата даты, не связанного с США - PullRequest
6 голосов
/ 17 мая 2010

У меня есть небольшое приложение MVC2, которое отображается в двух культурах: en-US и es-MX. Одна часть содержит пользовательский ввод для даты, которая предварительно заполнена текущей датой в модели.

При использовании en-US поле даты отображается в виде ММ / дд / гггг и может быть изменено в том же формате без каких-либо ошибок проверки.

При использовании es-MX поле даты отображается как дд / мм / гггг, но когда дата редактируется в этом формате, проверка на стороне сервера завершается неудачно с сообщением:

Значение '17 / 05/1991 'недопустимо для даты.

Одна из первых вещей, которая выскакивает у меня об этом сообщении, это то, что оно не локализовано. Как само сообщение (которое я не могу контролировать), так и отображаемое имя поля (которое я могу контролировать и локализовано в моем коде). Должен отображаться в локализованном формате.

Я попытался пройти по коду, чтобы точно определить, где происходит сбой проверки, но, похоже, это происходит внутри некоторого скомпилированного кода MVC или DataAnnotations, который я не вижу.

Сведения о приложении: IIS6, ASP.NET 3.5 (C #), MVC 2 RTM

Пример кода модели:

public class TestVieModel{
    [LocalizedDisplayNameDisplayName("TheDateDisplayName", NameResourceType=typeof(Resources.Model.TestViewModel))]
    [Required(ErrorMessageResourceName="TheDateValidationMessageRequired", ErrorMessageResourceType=typeof(Resources.Model.TestViewModel))]
    [DataType(DataType.Date)]
    public DateTime TheDate { get; set; }
}

Пример кода действия контроллера:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(TestViewModel model) {
    if(ModelState.IsValid) {  // <--- Always is false when using es-MX and a date foramtted as dd/MM/yyyy.
        // Do other stuff
        return this.View("Complete", model);
    }

    // Validation failed, redisplay the form.
    return this.View("Enter", model);
}

Пример кода:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<HispanicSweeps.Web.Model.LosMets.EnterViewModel>" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Test</title>
    </head>
    <body>
        <% using (Html.BeginForm()) {%>
            <%= Html.ValidationSummary(true) %>

            <fieldset>
                <legend>Fields</legend>
                <div class="editor-label">
                    <%= Html.LabelFor(model => model.TheDate) %>
                </div>
                <div class="editor-field">
                    <%= Html.EditorFor(model => model.TheDate) %>
                    <%= Html.ValidationMessageFor(model => model.TheDate) %>
                </div>

                <p><input type="submit" value="Save" /></p>
            </fieldset>

        <% } %>
    </body>
</html>

Ответы [ 2 ]

2 голосов
/ 25 мая 2010

Вот как я решил проблему в моем случае. Я вручную подтвердил дату в контроллере и сбросил ModelState для этого свойства:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(TestViewModel model) {

    var tempDate = new DateTime();
    var culture = CultureInfo.CurrentUICulture;

    if(DateTime.TryParse(Request.Form["TheDate"], culture, DateTimeStyles.None, out tempDate)) {
        model.DateOfBirth = tempDate;
        ModelState.Remove("TheDate");
        }

    if(ModelState.IsValid) {  // <--- Now valid
        // Do other stuff
        return this.View("Complete", model);
        }

    // Validation failed, redisplay the form.
    return this.View("Enter", model);
    }
1 голос
/ 17 мая 2010

Проверка происходит в классе DataAnnotations. Вы можете создавать подклассы классов DataAnnotations для своих собственных целей.

Я бы создал новый MultiCultureDateType класс DataAnnotations, который будет проверять даты в разных культурах.

Дополнительная информация: http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

...