日期时间的 MVC 模型绑定使用 GET 或 POST 是不同的
本文关键字:GET POST 是不同 绑定 时间 MVC 模型 日期 | 更新日期: 2023-09-27 18:34:39
我在对某个日期时间模型属性使用"远程"验证属性时遇到了以下不需要的行为。
在服务器端,我的应用程序区域性定义如下:
protected void Application_PreRequestHandlerExecute()
{
if (!(Context.Handler is IRequiresSessionState)){ return; }
Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-BE");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("nl-BE");
}
客户端,我的应用程序区域性定义如下所述:
Globalize.culture("nl-BE");
案例1:
模型属性
[Remote("IsDateValid", "Home")] public DateTime? MyDate { get; set; }
控制器操作
public JsonResult IsDateValid(DateTime? MyDate) { // some validation code here return Json(true, JsonRequestBehavior.AllowGet); }
- 调试
IsDateValid
方法时,在 UI 中输入的日期为05/10/2013
(2013 年 10 月 5 日(被错误地解释为10/05/2013
(2013 年 5 月 10 日(
案例2:
模型属性
[Remote("IsDateValid", "Home", HttpMethod = "POST")] public DateTime? MyDate { get; set; }
控制器操作
[HttpPost] public JsonResult IsDateValid(DateTime? MyDate) { // some validation code here return Json(true); }
- 调试
IsDateValid
方法时,在 UI 中输入的日期为05/10/2013
(2013 年 10 月 5 日(将正确解释为05/10/2013
(2013 年 10 月 5 日(
我是否缺少一些配置来使"标准"GET远程验证按预期工作?
当为 GET 绑定数据时,使用 InvariantCulture
(即"en-US"(,而对于 POST Thread.CurrentThread.CurrentCulture
则使用。背后的原因是 GET url 可能由用户共享,因此应该是不变的。而 POST 从不共享,使用服务器的区域性进行绑定是安全的。
如果您确定您的应用程序不需要在来自不同国家/地区的人员之间共享 url 的选项,则可以安全地创建自己的 ModelBinder
,即使对于 GET 请求,也会强制使用服务器区域设置。
下面是它在 Global.asax 中的外观示例.cs:
protected void Application_Start()
{
/*some code*/
ModelBinders.Binders.Add(typeof(DateTime), new DateTimeModelBinder());
ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeModelBinder());
}
/// <summary>
/// Allows to pass date using get using current server's culture instead of invariant culture.
/// </summary>
public class DateTimeModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
var date = valueProviderResult.AttemptedValue;
if (String.IsNullOrEmpty(date))
{
return null;
}
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
try
{
// Parse DateTimeusing current culture.
return DateTime.Parse(date);
}
catch (Exception)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, String.Format("'"{0}'" is invalid.", bindingContext.ModelName));
return null;
}
}
}