Internationalization with ASP.Net MVC3(User Select

2020-03-31 03:08发布

问题:

I want user to select preferred language once for the whole app. suggest me the easiest possible steps.
Such that user select preferred language only once just after login and then all app's view rendered with selected culture.
I found somehting related here


Because i am new in Internationalization i am not getting it properly.
I created a sample application which is working fine with browser specific Culture but here i want user to select preferred language.

回答1:

Typically, .NET will use the CultureSetting that best matches the user and then determines the appropriate resource file to use for globalization.

Once you have "saved" the users appropriate culture be in a database, session, or cookie.

What I do is change the thread to the appropriate language:

var language = "fr"; // Pull from your "saved" location (database, session, cookie, etc.)

// This changes UI only
Thread.CurrentThread.CurrentUICulture = new CultureInfo(language);

// This changes how number, date formatting is handled
Thread.CurrentThread.CurrentCulture = new CultureInfo(language);

Hope that helps!



回答2:

I propose you to extend User entity with Culture parameter to store it in DB. Then it possible to add information about user culture in Session for example (but any other technique also could be used)

then you need to add new Attribute with code

public class LocalizationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        try
        {
            string culture = UserSession.Culture;//Other mechanism of getting userinfo could be used there
            if (!string.IsNullOrEmpty(culture))
            {
                CultureInfo cultureInfo = new CultureInfo(culture); 
                Thread.CurrentThread.CurrentCulture = cultureInfo;
                Thread.CurrentThread.CurrentUICulture = cultureInfo;
            }
        }
        catch (Exception e)
        {
            Logger logger = new Logger();
            logger.LogException(e);
        }
    }
}

And add this attribute to all your controllers which should be localized



回答3:

One way to do it is with a cookie.

Assuming you have a drop-down list or some kind of input where the user can choose the language, have that input post to an action method. In that action method, write the language id to a cookie:

public class LanguageController
{
    [ActionName("change-to")]
    public virtual RedirectResult Change(LanguageChanger model)
    {
        var langCookie = new HttpCookie(CookieNames.Language);
        langCookie.Value = model.SelectedIsoCode;
        langCookie.Expires = DateTime.UtcNow.AddDays(28);
        HttpContext.Response.Cookies.Add(langCookie);
        return Redirect(model.ReturnUrl);
    }
}

You can then use an HttpModule to set the culture for every request. This way you know the culture is set throughout the entire request processing pipeline, instead of just when your controller actions execute:

public class CookieLocalizationModule : IHttpModule
{
    public void Dispose() { }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
    }

    void context_BeginRequest(object sender, EventArgs e)
    {
        // read the cookie (if any) and set the culture
        if (HttpContext.Current.Request.Cookies[CookieNames.Language] != null)
        {
            var cookie = HttpContext.Current.Request
                .Cookies[CookieNames.Language];
            var lang = cookie.Value;
            var culture = new System.Globalization.CultureInfo(lang);
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;
        }
    }

}

To register the module with IIS & IIS Express, see this web.config (note the Cassini config would be a little different)

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
        <add name="CookieLocalizationModule" 
            type="MyProject.CookieLocalizationModule, MyProject" />
    </modules>
    <handlers>
        ...