2013-05-28 10 views
7

staram się osiągnąć dwie rzeczy:Lokalizacja w ASP.NET MVC 4 stosując App_GlobalResources

  1. zlokalizować „wbudowane” Komunikaty o błędach dla „FieldMustBeDate” i „FieldMustBeNumeric”.
  2. Lokalizacja niektórych innych komunikatów o błędach, które można napotkać, na przykład "PropertyValueRequired".

Korzystając http://forums.asp.net/t/1862672.aspx/1 dla problemu 1 i 2 MVC 4 ignores DefaultModelBinder.ResourceClassKey dla problemu udało mi się dostać pracę zarówno lokalnie.

Jednak od razu po opublikowaniu na stronie internetowej "wbudowane" komunikaty o błędach domyślnie powracają do języka angielskiego, a pozostałe komunikaty o błędach pozostają zlokalizowane.

Przeczytałem kilka miejsc, w których należy unikać App_GlobalResources, jednak nie jestem w stanie wykonać problemu 1 bez użycia tego.

Utworzyłem plik .resx o nazwie "WebResources.resx", ustaw działanie kompilacji na "Embedded", ustaw opcję Copy to Output Directory na "Do no Copy", ustaw Narzędzie niestandardowe na "PublicResXFileCodeGenerator" i ustaw Przestrzeń nazw narzędzia niestandardowego na "Zasoby". Sam projekt jest ustawiony tak, aby publikować tylko potrzebne pliki.

My Global.asax.cs zawiera następujące istotne) (kod:

ClientDataTypeModelValidatorProvider.ResourceClassKey = "WebResources"; 
    DataAnnotationsModelValidatorProvider.RegisterAdapter(
    typeof(RequiredAttribute), 
    typeof(MyRequiredAttributeAdapter)); 

A MyRequiredAttributeAdapter klasa zawiera następujący kod:

public class MyRequiredAttributeAdapter : RequiredAttributeAdapter 
{ 
    public MyRequiredAttributeAdapter(
     ModelMetadata metadata, 
     ControllerContext context, 
     RequiredAttribute attribute 
    ) 
     : base(metadata, context, attribute) 
    { 
     if (attribute.ErrorMessageResourceType == null) 
     { 
      attribute.ErrorMessageResourceType = typeof(Resources.WebResources); 
     } 
     if (attribute.ErrorMessageResourceName == null) 
     { 
      attribute.ErrorMessageResourceName = "PropertyValueRequired"; 
     } 
    } 
} 

ta działa lokalnie jednak ktoś ma wszelkie pomysł, jak uruchomić komunikaty "wbudowane" po opublikowaniu?

Dziękuję za pomoc!

poważaniem, Andreas

Odpowiedz

5

Pomyślałem sobie ten jeden. Jeśli próbujesz osiągnąć powyższe, musisz oddzielić zlokalizowane komunikaty o błędach.

Utwórz plik * .resx dla innych komunikatów o błędach fx "PropertyValueRequired" i ustaw opcję Build Action na "Embedded", ustaw opcję Copy to Output Directory na "Do no Copy", ustaw narzędzie niestandardowe na "PublicResXFileCodeGenerator" i ustaw Przestrzeń nazw narzędzia niestandardowego na "Zasoby".

W moim przypadku zostały przeniesione "PropertyValueRequired" do pliku o nazwie LocalDanish.resx (nadal w folderze App_GlobalResources) i zmienił linię w moim "MyRequiredAttributeAdapter" z

attribute.ErrorMessageResourceType = typeof(Resources.WebResources); 

do

attribute.ErrorMessageResourceType = typeof(Resources.LocalDanish); 

Aby uzyskać komunikaty o błędach "wbudowane", należy utworzyć dwa pliki * .resx. Stworzyłem WebResources.resx i WebResources.da.resx. NIE zmieniaj niczego, pozostaw ustawienia domyślne (Build Action to "Content", itd.). Domyślam się, że strona automatycznie szuka pliku * .da.pliki resx w moim przypadku, ponieważ ustawiłem globalizację w moim WebConfig:

<globalization uiCulture="da-DK" culture="da-DK"/> 

Mam nadzieję, że to pomoże każdemu.

poważaniem, Andreas

+0

Dziękujemy! Ten problem doprowadza mnie do szaleństwa! – KTW

1

Zrobiłem kilka drobnych uzupełnień do oryginalnego postu, które nie przekładają wszystkie wiadomości w moim przypadku. (Długość ciągu i nieprawidłowe wartości właściwości)

Wykonaj powyższe kroki, aby utworzyć pliki * .resx, ustawić ich właściwości, a następnie ustawić ustawienia narodowe w pliku web.config, zgodnie z opisem firmy Andreas.

Następnie należy utworzyć parę adapterów:

// As described in original post: 
public class LocalizedRequiredAttributeAdapter : RequiredAttributeAdapter 
{ 
    public LocalizedRequiredAttributeAdapter(
     ModelMetadata metadata, 
     ControllerContext context, 
     RequiredAttribute attribute 
    ) 
     : base(metadata, context, attribute) 
    { 
     if (attribute.ErrorMessageResourceType == null) 
      attribute.ErrorMessageResourceType = typeof(Resources.Resources); 
     if (attribute.ErrorMessageResourceName == null) 
      attribute.ErrorMessageResourceName = "PropertyValueRequired"; 
    } 
} 

// Addition to original post: 
public class LocalizedStringLengthAttributeAdapter : StringLengthAttributeAdapter 
{ 
    public LocalizedStringLengthAttributeAdapter(
     ModelMetadata metadata, 
     ControllerContext context, 
     StringLengthAttribute attribute 
    ) 
     : base(metadata, context, attribute) 
    { 
     if (attribute.ErrorMessageResourceType == null) 
      attribute.ErrorMessageResourceType = typeof(Resources.Resources); 
     if (attribute.ErrorMessageResourceName == null) 
      attribute.ErrorMessageResourceName = "StringLengthAttribute_ValidationError"; 
    } 
} 

aw Global.asax.cx:

// Addition to original post: (Used for "PropertyValueInvalid") 
DefaultModelBinder.ResourceClassKey = "Resources"; 

// As described in original post: 
ClientDataTypeModelValidatorProvider.ResourceClassKey = "Resources"; 
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredAttribute), typeof(LocalizedRequiredAttributeAdapter)); 
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(StringLengthAttribute), typeof(LocalizedStringLengthAttributeAdapter));