johnkors / IdentityServer3.Contrib.Localization

Localization support for IdentityServer3
MIT License
19 stars 40 forks source link

change language #50

Closed farshid3003 closed 8 years ago

farshid3003 commented 8 years ago

I have a multilingual Identity server how can I change culture in run time ? if I set culture in configuration time so ti wont change in run time I think it should be change by current culture

johnkors commented 8 years ago

Yes, that's up to you how you do it.

IdSrv has it's documentation page for how you register services.

https://identityserver.github.io/Documentation/docsv2/advanced/customServices.html

fdipuma commented 8 years ago

As @johnkors says, you have to register the service not as a singleton, using something like this:

var factory = new IdentityServerServiceFactory
{
    LocalizationService = new Registration<ILocalizationService>(r => new GlobalizedLocalizationService(
        new LocaleOptions
        {
            Locale = CultureInfo.CurrentCulture.Name //remember to check if CurrentCulture is supported or it will throw
        }))
}
one-geek commented 8 years ago

@johnkors : your suggestion work only if we have access to the IdentityServerServiceFactory in a file other than the startup.cs (like in a BaseController.cs)

In my case, the declaration is in the startup.cs file and i can't redefined a new IdentityServerServiceFactory because i want it to be the same service declared in the startup.cs file.

startup.cs

IdentityServerServiceFactory idSvrFactory = new IdentityServerServiceFactory();
idSvrFactory.Register(
    new Registration<ILocalizationService>(r => new GlobalizedLocalizationService(
        new LocaleOptions
        {
            Locale = Thread.CurrentThread.CurrentCulture.Name.Equals("fr-CA") ? "fr-FR" : "Default"
        })
    )
);
BaseController.cs

public class BaseController : Controller
{
    // I need to be able to reset  IdentityServerServiceFactory locale from here
}
farshid3003 commented 8 years ago

Yes john is right

johnkors commented 8 years ago

@guerson : I'm not sure what you're actually trying to achieve, but it's possible that whatever you want to do in your BaseController might be done using the OwinContext and creating an adapter around GlobalizedLocalizationService and registering that instead.

Say

public class GlobalizedLocalizationServiceFactory : ILocalizationService
{
   private ILocalizationService _globalized
   public Global(OwinContextService owinservice)
   {
      var stuff = owinservice.GetStuff();
     _globalized = CreateGlobalizedBasedOnOwinContextStuff(stuff)
   }

   // implementation of ILocalizationService just passes calls to _globalized.
}
akshetty9 commented 8 years ago

@johnkors : I am also stuck with this exact same problem. I want to set the language based on user request say language code sent in URL or browser default language. To do this I register my dependency with default language in start up class as below.

options.Factory.LocalizationService = new Registration<ILocalizationService>(typeof(GlobalizedLocalizationService));

Now I am not sure what code should I write in imlementation of ILocalizationService to create instance based in language. If it has to read from OwinContextService, would like to know where should I inject the OwinContext with the langauage

farshid3003 commented 8 years ago

It must be a delegate or func rather than an instance. delegate handler should get the current culture from current thread

marzoukali commented 8 years ago

Also i want to achive the same thing i want to change language based on Browser accept-language tag i know that i can achive that by inject OwinEnvironementService into the localization service but any one have example on how to do that?

johnkors commented 8 years ago

@deserthero : I believe this is exactly what I gave a pseudo example of above.

akshetty9 commented 8 years ago

I tried this approach.

  1. Registered service as : options.Factory.LocalizationService = new Registration<ILocalizationService, GlobalizedLocalizationService>();
  2. In global.asax , I am reading user language from query string.
protected void Application_BeginRequest(Object sender, EventArgs e)
        {
            string locale = null;
            if (HttpContext.Current.Request.QueryString["LanguageCultureName"] != null && !String.IsNullOrWhiteSpace(HttpContext.Current.Request.QueryString["LanguageCultureName"]))
            {
                locale = HttpContext.Current.Request.QueryString["LanguageCultureName"];
                Thread.CurrentThread.CurrentCulture = new CultureInfo(locale);
            }
        }
  1. Changed constructor of service to set language from current culture.
public GlobalizedLocalizationService(LocaleOptions options = null)
        {

            var internalOpts = options ?? new LocaleOptions { Locale = Thread.CurrentThread.CurrentCulture.Name == "en-US" ? Constants.Default : 
                Thread.CurrentThread.CurrentCulture.Name };
            Validate(internalOpts);
            _service = LocalizationServiceFactory.Create(internalOpts);
        }

This is changing language per user. But I feel this is not clean. How can I avoid reading the language from query string using HttpContext, and use Owin instead.

Also, How can client pass this language to "Authorize" endpoint? Should it be passed in acr values?? Thanks in advance.

farshid3003 commented 8 years ago

Arc value and a coocie in ids

johnkors commented 8 years ago

From v.0.3, one can now make decisions based on the given OwinEnvironment (for instance request headers).

There's a sample in the idsrv samples repo:

https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/LocalizedMessages/LocalizedMessages/Startup.cs#L45

petteri-laine commented 7 years ago

Is there a sample on how to use the localized strings in the view templates?

johnkors commented 7 years ago

Yeah, for instance the default view service and the default views.

petteri-laine commented 7 years ago

So, for example, in this default template the uppercase Username should get localized: <label for="username">Username</label> Not working for me... :(

johnkors commented 7 years ago

Username is not part of the list of strings IdSrv let's us localize unfortunately. The ones available for translation are these:

https://github.com/IdentityServer/IdentityServer3/blob/master/source/Core/Resources/T4resx.cs