2013-07-17 25 views
6

MVCのDefaultModelBinderは、POST対GETリクエストの値(たとえば、double,DateTimeなど)を解析するために、異なる文化を使用することが判明しました。 Hereです。モデルバインディングで使用されるすべてのValueProviderResultのカルチャを指定した値に設定する方法はありますか?

これは、IValueProvider.GetValue()から返されたValueProviderResultオブジェクトのCultureプロパティによって制御されています。

私の質問はどのようにしてこの値が常にCultureInfo.InvariantCultureであることをグローバルに確認できますか。

私はカスタム値プロバイダを実装してこのようにすることができます。

私はカスタムモデルバインダーを実装して、このようにすることができます。

私はスレッドで文化を設定することができますが、残念ながらこれは私の場合はオプションではありません。

私が探しているのは、既定のモデルバインダーと既存のバリュープロバイダーでも、スレッドカルチャが設定されているかどうかにかかわらず、カルチャ不変の方法で解析できるように設定する方法です。

答えて

4

私の知る限り、あなたの基準に合う方法はありません。 は、あなたができることを知っていることの1つをしなければなりません(私は、最も適切な方法がカスタムバリュープロバイダーであると言います)。

理由:すべてのデフォルトのValueProviderは、CultureInfo.InvariantCultureまたはCultureInfo.CurrentCultureのいずれかになるようにハードコードされています。

internal FormValueProvider(
      ControllerContext controllerContext, 
      IUnvalidatedRequestValues unvalidatedValues 
     ) 
     : base(
       controllerContext.HttpContext.Request.Form, 
       unvalidatedValues.Form, 
       CultureInfo.CurrentCulture // <--- Grrr, argh 
     ) 
{ 
} 

文化はどこからでも検索されない(すなわち、上記の引数はデフォルトとして、しかし、1つの文化として使用されていません。ここで

は、具体的には、FormValueProviderはそれをしない方法です使用する)。

  • ChildActionValueProvider:にInvariantCulture
  • FormValueProvider:のCurrentCulture
  • JsonValueProvider参照のために異なるIValueProviders

    培養物は、これらは、デフォルトIValueProvidersの各々のために培養されています:CurrentCulture

  • RouteDataValueProvider:にInvariantCulture
  • QueryStringValueProvider:にInvariantCulture
  • HttpFileCollectionValueProvider:見られるように、以来、FormValueProviderを置き換えるために、巨大な作業ではありませんCurrentCulture IValueProviders

    の交換にInvariantCulture

上の例では、基本クラス '(NameValueCollectionValueProvider)コンストラクタを呼び出します。これは、目的のカルチャを取ります議論として。

FormValueProvider の元の実装では、実際にはより困難になるように、表面上にが表面に現れ、内部クラスとインタフェースを参照しています。しかし、彼らはプロバイダを置き換えるために必要ではありません - 彼らはユニットテストのためだけにあります。 Request.FormsValidation.Unvalidated(Request)Forms性(静的メソッド):

あなたは2つのだけNameValueCollection取得が容易であるSを通過する、(上述したように)ベースのコンストラクタを呼び出す必要があります。そして、あなたが望む文化に第3引数を設定します。

FormValueProviderFactoryはさらに簡単です。

JsonValueProviderは、もう少し複雑です - 基本的に、あなたは新しいクラスにJsonValueProviderFactoryのソースをコピーして、それを修正する必要があるだろう - それはGetValueProvider()をオーバーライドできますが、その方法は、主に他のprivate staticメソッドへの呼び出しで構成されているため。

EDIT(Petar Ivanov):これは私のために働いた。それを動作させるためにはValueProviderFactories.Factoriesにカスタムファクトリを追加するだけでは不十分でした。これはFormValueProviderFactoryの後に追加されます。代わりに、FormValueProviderFactoryをカスタムのものに置き換えなければなりませんでした。

+0

お返事ありがとうございます。私は、デフォルトのプロバイダーのどれがCurrentCultureを使用しているのかわからなかったと思います(したがって私は拡張が必要です)ので、より一般的なソリューションを探していました。 –

+0

リストを追加しました。私は 'Session'と' TempData'を削除しました。これらはMVC Futuresの一部であり、デフォルトでは使用されていません - CookieとServerVariableでも同じです。それらのすべては 'InvariantCulture'を使用します。 – JimmiTh

関連する問題