【问题标题】:MVC Model Binding for DateTime is different using GET or POSTDateTime 的 MVC 模型绑定使用 GET 或 POST 不同
【发布时间】:2013-10-10 09:59:19
【问题描述】:

在对某个 DateTime 模型属性使用“远程”验证属性时,我遇到了以下不良行为。

服务器端,我的应用程序文化定义如下:

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");

案例一:

  • 模型属性

    [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 远程验证按需要工作的一些配置?

【问题讨论】:

  • 调试使用什么文化来解析视图中的日期

标签: c# asp.net-mvc asp.net-mvc-4 internationalization model-binding


【解决方案1】:

当为 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;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 2015-08-15
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多