2

我正在尝试将复杂的视图模型传递给控制器​​操作。传递的对象是 Goal 类型,其中包含一个日期时间属性 (Goal.moddate)。在我的情况下,日期的字符串表示遵循 es-MX。因此,2012 年 2 月 29 日表示为“29/02/2012”(我对其他日期也有同样的问题)。

控制器动作还使用 [CultureAwareAction] 属性进行注释 - 此属性根据用户偏好设置文化信息。在这种情况下(更新以使解决方案更清晰)

public class CultureAwareActionAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);    
        Thread.CurrentThread.CurrentCulture = new CultureInfo("es-MX");
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("es-MX");
    }
}

我处理该操作的首选方式如下:

    [HttpPost]
    [CultureAwareAction]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(Goal goal)
    {
        try
        {
            if (ModelState.IsValid)
            {
                {
                    ...update logic ... 
                }
            }
        }
        catch (DataException)
        {
           ... error handling ....   
        }
        return View();
    } 

使用此方法 ModelState.IsValid 由于未解析日期字符串而返回 false。将控制器操作更改为以下我没有遇到错误:

    [HttpPost]
    [CultureAwareAction]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(int id, FormCollection formcollection)
    {
        try
        {
            Goal goal = unitOfWork.GoalRepository.GetByID(id);

            if (TryUpdateModel(goal,formcollection))
            {
                {
                   ... update logic ....
                }
            }
        }
        catch (DataException)
        {
          ... error handling ...
        }
        return View();
    }

我的目标是在第一种情况下强制执行适当的全球化行为,因为这种方法具有显着优势。除非在使用 [CultureAwareAction] 属性设置用户首选文化之前发生模型绑定,否则这似乎应该有效。

4

1 回答 1

3

模型绑定器使用CurrentCulture,而不是CurrentUICulturewhen 解析日期。此外,您还没有显示此代码,CultureAwareAction但很可能它在模型绑定之后执行,因此您设置文化为时已晚。

如果您想确保它在模型绑定之前执行,您可以实现IAuthorizationFilter接口:

public class CultureAwareActionAttribute : ActionFilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        // That's for displaying in the UI, the model binder doesn't use it
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("es-MX");

        // That's the important one for the model binder
        Thread.CurrentThread.CurrentCulture = new CultureInfo("es-MX");
    }
}
于 2012-06-14T05:50:56.710 回答