Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to safely get localized string in Web Api Controllers?

I am trying to localize responses of my web api.

I created a Resource file (Messges.resx) in my project containing all the strings that are localized. And using Accept-Language header to identify user's language.

In the responses I can set the string as:

response = Messages.KEY_GOOD_MORNING

which will get the string for that name in language of the current thread culture. I will have to change thread's current culture to the culture found from Accept-Language header. But I don't want to change the culture of the thread since this will also change number/date formatting which is problematic for me.

Another alternative I see is- using ResourceManager and passing the culture as-

Messages.ResourceManager.GetString("KEY_GOOD_MORNING", CultureInfo.CreateSpecificCulture(lang.value))

This way I won't have to change the culture of the thread. But the problem with this approach is- string names aren't type safe anymore. A typo in the string name passed to GetString() may result into null values returned.

Is there any other approach I can adopt to avoid both the problems above?

like image 227
Quark Avatar asked Feb 26 '17 20:02

Quark


2 Answers

Firstly you should be check this msdn discussion

For best approach for this problem. You should be set globalization setting on your web.config file.

<configuration>
 <system.web>
  <globalization 
    enableClientBasedCulture="true|false"
    requestEncoding="any valid encoding string"
    responseEncoding="any valid encoding string"
    fileEncoding="any valid encoding string"

    responseHeaderEncoding = "any valid encoding string" 
    resourceProviderFactoryType = string
    enableBestFitResponseEncoding = "true|false"

    culture="any valid culture string"
    uiCulture="any valid culture string"/>

For English culture case

<globalization 
    enableClientBasedCulture="false" 
    uiCulture="en-US" 
    culture="en-US" />

With that you'll be able to use culture thread with config. Also you can be set culturethread with browser settings to auto, you can be set to auto and ignore some cases. For more information you can check link above.

If you want to accept browser's culture

<globalization 
    enableClientBasedCulture="true" 
    uiCulture="auto" 
    culture="auto" />

Or with default action

<globalization 
    enableClientBasedCulture="true" 
    uiCulture="auto:en-US" 
    culture="auto:en-US" />

For best practice don't you ever change your computer thread culture info. But you can change session based change current thread culture, it's just thread based info not the all system. I hope it'll be usefull.

like image 145
orhun.begendi Avatar answered Sep 18 '22 04:09

orhun.begendi


Just a thought, but you could use your approach and use the nameof() construct/keyword to keep type safety - as that was your question initially "ut the problem with this approach is- string names aren't type safe anymore. A typo in the string name passed to GetString() may result into null values returned."

Example using nameof:

Messages.ResourceManager.GetString(nameof(Messages.KEY_GOOD_MORNING), CultureInfo.CreateSpecificCulture(lang.value))

What it does & documentation:

  • The compiler will then emit the string as "KEY_GOOD_MORNING", but you get to keep all the refactoring/renaming/type safe goodie stuff.
  • This is only available as of C# 6.0
  • Reference to documentation: https://msdn.microsoft.com/nl-be/library/dn986596.aspx
like image 38
Yves Schelpe Avatar answered Sep 19 '22 04:09

Yves Schelpe