2

複雑なビューモデルをコントローラーアクションに渡そうとしています。渡されるオブジェクトのタイプはGoalであり、特にdatetimeプロパティ(Goal.moddate)が含まれています。私の場合、日付の文字列表現はes-MXに従います。したがって、2012年2月29日は「2012年2月29日」と表示されます(他の日付でも同じ問題が発生します)。

コントローラアクションにも[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するときに ではなくを使用します。CurrentUICultureまた、このコードを示していませんが、モデル バインディングの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 に答える