2013-07-17 5 views
6

Okazuje się, że MVC DefaultModelBinder wykorzystuje różne kultury do analizowania wartości (na przykład double, DateTime itd.) Dla żądań POST i GET. Here to więcej informacji.Jak ustawić kulturę wszystkich ValueProviderResult używaną w powiązaniu modelu z podaną wartością?

Widzę, że jest to kontrolowane przez właściwość Culture obiektów ValueProviderResult, które są zwracane z IValueProvider.GetValue().

Moje pytanie brzmi: Jak mogę globalnie upewnić się, że ta wartość jest zawsze CultureInfo.InvariantCulture.

Wiem, że mogę wdrożyć dostawców wartości niestandardowych i zrobić to w ten sposób.

Wiem, że mogę zaimplementować niestandardowe segregatory modeli i zrobić to w ten sposób.

Wiem, że mogę ustawić kulturę w wątku, ale niestety nie jest to opcja w moim przypadku.

To, czego szukam, to sposób na ustawienie go tak, aby nawet domyślny segregator modelu i istniejący dostawca wartości potrafiły parsować w sposób niezmienny kultury, niezależnie od tego, w jakim ustawiona jest kultura wątku.

Odpowiedz

4

O ile mi wiadomo, nie ma sposobu, aby pasowało do twoich kryteriów. You będzie zrobić jedną z rzeczy, które wiesz, że możesz zrobić (powiedziałbym, że najbardziej odpowiedni sposób byłoby dostawcą wartości niestandardowej).

Powód: Wszyscy domyślni dostawcy wartości są na stałe oznaczeni za pomocą CultureInfo.InvariantCulture lub CultureInfo.CurrentCulture.

Tutaj, w szczególności, jest sposobem FormValueProvider robi:

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

Kultura nie jest pobierana od nigdzie indziej (czyli powyżej argument nie jest używany jako domyślny, ale jako jednej kultury używać).

Hodowle różnych IValueProviders

Dla porównania, są to hodowle dla każdego z domyślnych IValueProviders:

  • ChildActionValueProvider: InvariantCulture
  • FormValueProvider: CurrentCulture
  • JsonValueProvider : CurrentCulture
  • RouteDataValueProvider: InvariantCulture
  • QueryStringValueProvider: InvariantCulture
  • HttpFileCollectionValueProvider: InvariantCulture

Wymiana CurrentCulture IValueProviders

nie jest to ogromne zadanie zastąpić FormValueProvider, ponieważ, jak widać powyżej, po prostu wywołuje konstruktor klasy podstawowej "(NameValueCollectionValueProvider) - który przyjmuje pożądaną kulturę jako argument.

Pierwotna implementacja FormValueProvider pojawia się na powierzchni, która jest trudniejsza niż w rzeczywistości, z odniesieniami do klas wewnętrznych i interfejsów. Ale nie są one potrzebne, aby zastąpić dostawcę - są one dostępne tylko do testowania jednostkowego.

Wystarczy wywołać konstruktora bazowy (jak wspomniano powyżej), przechodząc dwa NameValueCollection s, które są łatwe do nabycia: Request.Forms i właściwość Forms z Validation.Unvalidated(Request) (metoda statyczna). I ustaw trzeci argument na pożądaną kulturę.

Model FormValueProviderFactory jest jeszcze prostszy.

JsonValueProvider jest nieco bardziej zaangażowane - w zasadzie trzeba by skopiować źródło JsonValueProviderFactory do nowej klasy i zmodyfikować go - bo choć pozwala nadrzędny GetValueProvider(), że metoda składa się głównie z połączeń do innych private static metod.

EDYCJA (Petar Ivanov): To zadziałało dla mnie. Aby to działało, nie wystarczyło dodać niestandardowej fabryki do ValueProviderFactories.Factories, ponieważ w ten sposób jest ona dodawana po FormValueProviderFactory. Zamiast tego musiałem zastąpić FormValueProviderFactory niestandardową.

+0

dzięki za odpowiedź. Sądzę, że nie byłem pewien, który z domyślnych dostawców korzysta z CurrentCulture (i dlatego muszę rozszerzyć), więc szukałem bardziej ogólnego rozwiązania. –

+0

Dodano listę. Usunąłem 'Session' i' TempData' - są to części MVC Futures i dlatego nie są używane domyślnie - to samo dotyczy 'Cookie' i' ServerVariable'. Wszystkie te używają "InvariantCulture". – JimmiTh

Powiązane problemy