1

(Skip this for a TL;DR version)

I am trying to let the user set his prefered language of my website using an option in his profile. I got it all working at 99%: AccountController saves the culture when the user updates his profile and set a cookie "language". The website will then change its displayed language perfectly. However, I still need to set the website language when the user sign-in the first time without him having to update his profile to create the cookie.

So, I am trying to set the cookie early in the app cycle by overriding the Initialize() function of my base controller. The problem is that I can't access the user preference as UserManager is null. Is there a way to access my user's language preference saved in the database from the initialize() function of the baseController?

TL;DR version: userManager is null in initialize() function of the baseController. How can I access the current user variables from there ?

     protected override void Initialize(RequestContext requestContext)
    {
        try
        {
            String culture = requestContext.HttpContext.GetOwinContext().Request.Cookies["language"];
            if(culture != null)
            {
                Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(culture);
                Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
            }
            else
            {
                if (requestContext.HttpContext.User.Identity.IsAuthenticated)
                {
                    String userName = requestContext.HttpContext.User.Identity.GetUserName();
                    ApplicationUser user = UserManager.FindByName(userName); //TODO: UserManager is NULLL !!!

                    HttpCookie language = new HttpCookie("language");
                    if (user.DefaultLanguage)
                    {
                        language.Value = "fr-CA";
                    }
                    else
                    {
                        language.Value = "en-CA";
                    }
                    Response.Cookies.Add(language);
                }

            }
        }
        catch (Exception e)
        {

        }
        base.Initialize(requestContext);

    }

1 Answer 1

1

I just read the question again. I have some small changes in the answer.

You shouldn't use UserManager at all for this. Just add a claim to the ClaimsIdentity with the language. This also prevents an extra call to the database.

Add the language property to the AppicationUser. Make sure it is added as claim:

public class ApplicationUser : IdentityUser
{
    public string Language { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

        // Add custom user claims here
        userIdentity.AddClaim(new Claim("Language", Language));

        return userIdentity;
    }
}

In Initialize you can read the claim like this:

 protected override void Initialize(RequestContext requestContext)
{
    try
    {
        // Try claims collection first
        var culture = (System.Security.Claims.ClaimsIdentity)User.Identity).FindFirst("Language").Value;

        // otherwise try cookie
        if (culture == null)
            culture = requestContext.HttpContext.GetOwinContext().Request.Cookies["language"];

        if (culture == null)
        {
            // user is not logged in and there is no cookie
            culture = "fr-CA";
            HttpCookie language = new HttpCookie("language");
            language.Value = culture;
            Response.Cookies.Add(language);
        }
        Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(culture);
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
    }
    catch (Exception e)
    {
    }
    base.Initialize(requestContext);
}

Something like this. Still didn't test it, but this is the idea. Please let me know if something is not clear.

Sign up to request clarification or add additional context in comments.

2 Comments

Hey, I big thanks for your answer! I am currently trying to make this work and I will get back to you as soon as possible with an update
It works PERFECTLY!! I just had to change some lines for it to work : var identity = (ClaimsIdentity)requestContext.HttpContext.User.Identity; [linebreak]culture = identity.FindFirst("language").Value; and requestContext.HttpContext.GetOwinContext().Response.Cookies.Append("language", culture);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.