ASP.NET MVC3: заставить контроллер использовать формат даты дд / мм / гггг - PullRequest
13 голосов
/ 12 декабря 2011

По сути, мой указатель даты использует британский формат dd/mm/yyyy. Но когда я отправляю форму, ASP.net явно использует американский формат. (принимает только дни, если меньше 12, т.е. считает, что это месяц.)

 public ActionResult TimeTable(DateTime ViewDate)

Есть ли способ заставить его распознавать определенный способ?

Как ни странно, другие методы вставки распознают правильный формат.

"Словарь параметров содержит пустую запись для параметра ViewDate не обнуляемого типа System.DateTime для метода System.Web.Mvc.ActionResult Index(System.DateTime) в Mysite.Controllers.RoomBookingsController. Необязательный параметр должен быть ссылочным типом, обнуляемым типом или быть объявленным в качестве необязательного параметра. "

Ответы [ 6 ]

16 голосов
/ 12 декабря 2011

Прочитайте это . Это дает хорошее объяснение того, что происходит и почему оно работает так, как оно работает.

Я нахожусь в ситуации, когда я знаю, что все, кто пользуется сайтом, находятся в Великобритании, поэтому я могу смело переопределить связующее для модели DateTime по умолчанию:

public class DateTimeModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var date = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;

        if (String.IsNullOrEmpty(date))
            return null;

        bindingContext.ModelState.SetModelValue(bindingContext.ModelName, bindingContext.ValueProvider.GetValue(bindingContext.ModelName));
        try
        {
            return DateTime.Parse(date);
        }
        catch (Exception)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, String.Format("\"{0}\" is invalid.", bindingContext.ModelName));
            return null;
        }
    }
}
3 голосов
/ 12 декабря 2011

Вам нужно использовать собственный ModelBinder для вашего DateTime. У меня была та же проблема, что и у вас.

2 голосов
/ 13 декабря 2011

Вы можете сделать это:

  • глобально (в global.asax в Application_Start ()):

    ModelBinders.Binders.Add(typeof(DateTime), new DateTimeModelBinder()); 
    
  • для метода:

        public ActionResult TimeTable([Binder(typeof(DateTimeModelBinder)]DateTime ViewDate)
    
  • для пользовательского класса модели - нет, нет возможности, потому что вы используете struct DateTime; -)

Ах, извините, я не смог добавить комментарий к посту Адамса - он основан на его коде.

2 голосов
/ 12 декабря 2011

В основном мой сборщик дат использует британский формат дд / мм / гггг

Ошибка новичка.Он должен использовать любой формат, установленный браузером.Проблема не в формате, а в разных форматах между клиентом и сервером.Сервер должен выдать код, который форматирует дату в соответствии с согласованной локалью, которую сервер затем также использует для ее анализа.

Но когда я отправляю форму, ASP.NET явно использует формат США.

Нет.Это говорит о том, что когда я принимаю специю, это всегда соль, а потом ты всегда принимаешь соль.Ваш сервер принимает текущую согласованную культуру, которая - если вы не изменяете настройки - согласовывается между клиентом и сервером.Проверьте текущую культуру потоков, когда она должна выполнить синтаксический анализ, чтобы увидеть, для чего она установлена.

2 голосов
/ 12 декабря 2011

Вы пытались установить текущую культуру как en-GB?

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
     base.Initialize(requestContext);

     CultureInfo cultureInfo = CultureInfo.GetCultureInfo("en-GB");

     Thread.CurrentThread.CurrentCulture = cultureInfo;
     Thread.CurrentThread.CurrentUICulture = cultureInfo;                    
 }
0 голосов
/ 13 декабря 2011

Из моего BindigTools для привязки DateTime? (Nullable), по образцу книги - Pro MVC3

    public static DateTime? GetValueNDateTime(ModelBindingContext context, string searchPrefix, string key, string format)
    {
        ValueProviderResult vpr = context.ValueProvider.GetValue(searchPrefix + key);
        DateTime outVal;
        if (DateTime.TryParseExact(vpr.AttemptedValue, format, null, System.Globalization.DateTimeStyles.None, out outVal))
        {
            return outVal;
        }
        else
        {
            return null;
        }
    }

Он использует точный синтаксический анализ, поэтому у вас не должно возникнуть проблем с разбираемыми датами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...