Передача DateTime контроллеру через URL-адрес, вызывающий ошибку в ASP.NET MVC 3 (культура)
Мое приложение настроено с культурой pt-BR (Date dd-mm-yyyy) в web.config:
<globalization enableClientBasedCulture="false" requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="iso-8859-15" responseHeaderEncoding="utf-8" resourceProviderFactoryType="string" enableBestFitResponseEncoding="true" culture="pt-BR" uiCulture="pt-BR" />
Все DateTime, созданные в моей системе, находятся в правильном формате, но я создал такой метод контроллера:
public ActionResult Test(DateTime date)
{
}
Вызов этого метода прямо в браузере передает значение null, когда дата имеет формат portuguese-br, например:
mysite/Test/?date=19/01/2012 => date = null in my controller
mysite/Test/?date=01/01/2012 => date is fine, but in US format (mm-dd-yyyy)
Как я могу исправить это, чтобы принять формат даты?
Ответы
Ответ 1
Там есть ушата с по умолчанию, что не так просто знать, но как только вы это знаете, вы больше не совершаете ту же ошибку:
-
Когда вы используете запрос POST, связующее устройство по умолчанию использует настройки вашей культуры для анализа дат.
-
Когда вы используете запрос GET, связующее устройство по умолчанию использует CultureInfo.InvariantCulture
для анализа дат и игнорирует текущие настройки культуры.
Поскольку вы используете запрос GET и передаете дату в качестве параметра строки запроса, вы должны отформатировать его с использованием формата культуры инварианта при отправке его в URL-адрес. Правильный способ форматирования даты в качестве параметра строки запроса - yyyy-MM-dd
.
Вы можете ознакомиться с следующим сообщением в блоге, в котором содержится подробная информация.
Ответ 2
Как человек, который много работает с американскими компаниями, у меня был большой опыт работы с проблемами даты.
Мой лучший совет - выбрать нечеткий формат при передаче.
dd-MMM-yyyy
и
yyyy-MM-dd
Являются безопасными ставками и будут успешно проанализированы с помощью DateTime.Parse(obj).
Если изменить формат даты, это не вариант, вы должны посмотреть DateTime.ParseExact
, который позволяет указать точную строку формата, после которой вы будете.
Ответ 3
Один из подходов заключался бы в том, чтобы принять дату в виде строки, а затем манипулировать ею в контроллере с правильным языком/культурой.
Ответ 4
Получается та же проблема, используя @Html.Action(..)
в представлении. Для этой ситуации это можно решить, поставив DateTime
в модель:
public class MyModel
{
public DateTime Value {get;set;}
}
и в представлении:
@Html.Action("MyAction", new { myModel })
Обратите внимание на new { }
вокруг экземпляра MyModel
, таким образом DateTime
не преобразуется в строку. Это решение работает только для Html.Action()
и не для Html.ActionLink()
или Url.Action()
, поскольку MVC выполняет myModel.ToString()
в URL-адресе.