Not getting .Resx based on CurrentUICulture

2.6k views Asked by At

I have the following two files in my MVC project:

enter image description here

I am setting the culture in my global.asax like so:

Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");

I can see in the Immediate Window in Visual Studio that the value of Thread.CurrentThread.CurrentUICulture is "de-DE" at the time of rendering the view.

Which brings me to my view:

@Html.Raw(CurrentUICultureContent.ce_landingPage_welcomeText)

The problem is, it only renders the text from CurrentUICultureContent.resx and not the text from CurrentUICultureContent.de.resx even though the CurrentUICulture is set to "de-DE."

Note: I have also tried changing the file name to CurrentUiCultureContent.de-DE.resx but that doesn't seem to work either.

Edit: I put a breakpoint in my view page and checked the value of the CurrentUICulture in the Immediate Window; but it still doesn't get the text from the "de-DE.resx" file:

System.Threading.Thread.CurrentThread.CurrentUICulture {de-DE}
    Calendar: {System.Globalization.GregorianCalendar}
    CompareInfo: {CompareInfo - de-DE}
    CultureTypes: SpecificCultures | InstalledWin32Cultures | FrameworkCultures
    DateTimeFormat: {System.Globalization.DateTimeFormatInfo}
    DisplayName: "German (Germany)"
    EnglishName: "German (Germany)"
    IetfLanguageTag: "de-DE"
    IsNeutralCulture: false
    IsReadOnly: false
    KeyboardLayoutId: 1031
    LCID: 1031
    Name: "de-DE"
    NativeName: "Deutsch (Deutschland)"
    NumberFormat: {System.Globalization.NumberFormatInfo}
    OptionalCalendars: {System.Globalization.Calendar[1]}
    Parent: {de}
    TextInfo: {TextInfo - de-DE}
    ThreeLetterISOLanguageName: "deu"
    ThreeLetterWindowsLanguageName: "DEU"
    TwoLetterISOLanguageName: "de"
    UseUserOverride: true

Why is it returning English instead of the expected German resource file?

Is there something extra that I have to do to get this to work?

3

There are 3 answers

0
user1477388 On BEST ANSWER

Sorry for this question - the problem here was just that we were manually loading the assemblies (shadow copying them) and the existing logic didn't put the resource.DLL in the correct folder. .NET expects for the resource.DLL to be placed in the corresponding culture folder; i.e.:

  • /Shadow_copy_folder
    • /en
      • /resource.dll

Once I updated the logic to create the shadow copy folder for the culture; .NET picked out the correct resource file.

Also, there was something wrong with the way I was specifying the culture. Apparently, it must be done like this:

Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("de-DE");
2
Sayan Pal On

One way to apply multilingual resource file support in MVC is to mark the resource file as an Embedded Resource. That way you can make use of the resource file as simple class.

To mark your resource file as Embedded Resource you can do the following as shown on the image below:

  1. Change the access modifier of the resource file to Public.

Public Modifier

  1. Next change the following properties of the resource file as shown below. You are free to choose the custom tool namespace as per your wish:

Change Properties

  1. Now make use of the custom tool namespace on the view to get the current culture specific text.

Using on the view

Please note that this is an old code and still works for me without doing anything radically different. Hope this somewhat answers your query.

EDIT: As mentioned below in my comment here is the global action filter. Let me know if this suits your purpose.

public class PersonalizeAttribute:ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string language = (string)(filterContext.RouteData.Values["language"] ?? "en");
        string culture = (string)(filterContext.RouteData.Values["culture"] ?? "US");

        CultureInfo ci = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture));

        Thread.CurrentThread.CurrentCulture = ci;
        Thread.CurrentThread.CurrentUICulture = ci;
    }
}

 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new PersonalizeAttribute());
    }

And yeah I read the culture information from URL (you can also make use of Server variables to catch hold of the preferred culture of the user).

routes.MapRoute(
            name: "",
            url: "{language}-{culture}/{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, language = "en", culture = "US" }
        );
0
Ashwath On

Override the executeCore() of a Controller and set both

Thread.CurrentThread.CurrentCulture and Thread.CurrentThread.CurrentUICulture

After the build make sure you have the respective resource file in bin folder of your MVC project and also make sure you have a installer script to pick up this files so that you will not have any problem in Testing environment.

good luck...