首页 > 解决方案 > 本地化和全球化 ASP.NET Core MVC 3.1 所有视图

问题描述

我有一个应用程序,用户必须先登录才能访问他们的记录,到目前为止,我已经能够使用此处找到的本教程本地化(翻译)登录页面,但是当他们登录时,页面默认返回 en-GB (这是默认语言)。

我的问题是如何使选择的语言成为用户打开时整个页面使用的语言?

在 startup.cs 我有这个:

 (IServiceCollection services Method)
 services.AddLocalization(opt => { opt.ResourcesPath = "Resources"; });
        services.AddMvc(opts =>
        {
            opts.Filters.Add<SerilogLoggingActionFilter>();               
        }).AddRazorRuntimeCompilation().AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
            .AddDataAnnotationsLocalization(); 
       CultureInfo[] supportedCultures = new[]
 {
    new CultureInfo("en"),
    new CultureInfo("fr")
};

        services.Configure<RequestLocalizationOptions>(options =>
        {
            options.DefaultRequestCulture = new RequestCulture("en");
            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;
            options.RequestCultureProviders = new List<IRequestCultureProvider>
    {
        new QueryStringRequestCultureProvider(),
        new CookieRequestCultureProvider()
    };
        });

然后在 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 方法中我有:

      app.UseRequestLocalization(app.ApplicationServices.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value);
app.UseEndpoints(endpoints =>
        {
           
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            
        });

我创建了一个 partialView 来允许用户选择语言,这里是部分视图:

@{
   var requestCulture = Context.Features.Get<IRequestCultureFeature>();
   var cultureItems = locOptions.Value.SupportedUICultures
    .Select(c => new SelectListItem { Value = c.Name, Text = localizer.GetString(c.Name) }).ToList();

   var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~ 
  {Context.Request.Path.Value}{Context.Request.QueryString}";
  }
 
 <form asp-controller="Home" asp-action="SetLanguage" asp-route-returnUrl="@returnUrl" method="post" 
 class="form-horizontal" role="form">
  @Html.AntiForgeryToken()

  @if (requestCulture != null)
  {
  <input type="hidden" name="currentCulture" value="@requestCulture.RequestCulture.UICulture.Name"/>}
 <select name="culture" onchange="this.form.submit();"asp-   for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems"></select>

正如您从部分视图中看到的那样,当用户选择他们的语言时,它会被发送到 Home 控制器,这里的“SetLangauge”方法就是该方法:

 [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult SetLanguage(string culture, string returnUrl)
    {

        CultureName = culture;

        Response.Cookies.Append(

            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
            new CookieOptions { Expires = DateTimeOffset.UtcNow.AddDays(30) });

        return LocalRedirect(returnUrl);
    }

这种方法显然使用 'Cookie' 方法来保存所选语言,但是,正如我所说,一旦用户登录,它默认返回为 'en-GB'

上面的所有方法都可以与我的资源文件夹一起使用,只需要一种方法让它在其他页面上工作吗?

谢谢 - 很抱歉它很长,但这就是我根据我提供的教程链接所拥有的。感谢您抽出宝贵时间 - 我在这里到处搜索,但仍然无法在其他页面上运行。

//EDITED VERSION 登录页面视图如下所示

@model PropGlobalise.Models.UserViewModel
@inject Microsoft.AspNetCore.Mvc.Localization.IViewLocalizer localizer

<form asp-controller="Home" asp-action="Login" method="post">   

@ViewData["CurrentCulture"] //for debugging only
<div class="ml-auto mt-4"> 
<input asp-for="EmailAddress" type="email" 
placeholder="@localizer["emailAddress"]" > 
</div> <br />

<div class="ml-auto mt-4">
<input asp-for="Password" type="password" 
placeholder="@localizer["password"]"></div> <br />

<div class="ml-auto mt-4">
<a class="signInText" style="cursor: pointer;  float:right;" onclick="@(" 
window.location.href='" + @Url.Action("ForgottenPassword", "Users") + 
"' ");">@localizer["forgotPassword"]</a>

<a style="cursor: pointer; margin-left: "onclick="@(" 
window.location.href='" + @Url.Action("Create", "Users") + "' 
");">@localizer["registerNewUser"]</a></div></div>
                       
<div class="gform_footer top_label">
<input type="submit" id="gform_submit_button_1" 
class="gform_button button" value="@localizer["login"]">
<div>
                                   
</form>

在登录视图中,@ViewData["CurrentCulture"]显示了用户从语言下拉列表中选择的语言,例如显示英语的 en 和法语的 fr,Home 控制器如下所示:

[TempData]
  public string LanguageSelected { get; set; }
    [HttpGet]
    [AllowAnonymous]
    public IActionResult Index() 
    {
        CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;      
        LanguageSelected = currentCulture.ToString();
       
        ViewData["CurrentCulture"] = currentCulture;

        
        return View();
    }

我尝试将LanguageSelected保存为 TempData,以便它使用所选语言重定向到下一个视图。因此,当用户单击登录时,他们看到的下一个视图页面(即“记录”)在控制器操作视图中具有以下内容:

  public IActionResult Records()
    {
        Thread.CurrentThread.CurrentCulture = 
   CultureInfo.CreateSpecificCulture((LanguageSelected).ToString());
        Thread.CurrentThread.CurrentUICulture = new 
   CultureInfo((LanguageSelected).ToString());
        TempData.Keep();
  }

这似乎可行,即用户被重定向到所选语言的下一个视图。但是当您在页面之间单击时,控制器中的“LangaugeSelected”被设置回“null”——这是由具有排序寿命的 TempData 引起的。那么无论如何我可以长时间保留所选语言吗?有人提到'queryString',但我不确定如何继续。

谢谢你。

标签: asp.netviewlocalizationasp.net-core-mvcglobalization

解决方案


推荐阅读