【问题标题】:ASP .NET Core 1.0 RTM Localization not workingASP .NET Core 1.0 RTM 本地化不起作用
【发布时间】:2016-12-14 21:02:21
【问题描述】:

我一直在尝试按照microsofts documentation 为我的 asp .NET Core 1.0 RTM Web 应用程序实现本地化,但我无法让它工作。我遇到的问题是,无论我如何尝试设置文化,它总是显示来自英语资源文件的字符串。

如果有人有 5 分钟的时间,我将非常感谢您的意见。

这是我关于本地化的 Startup.cs 内容:

public void ConfigureServices(IServiceCollection services)
{
  ...
  services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.SubFolder)
    .AddDataAnnotationsLocalization();
  services.AddScoped<LocalizationFilter>();
  services.AddLocalization(options => options.ResourcesPath = "Resources");

  var supportedCultures = new List<CultureInfo>{
     new CultureInfo("en-US"),
     new CultureInfo("sl-SI"),
     new CultureInfo("de-DE"),
     new CultureInfo("hr-HR")
  };
  services.Configure<RequestLocalizationOptions>(options =>
  {
     options.SupportedCultures = supportedCultures;
     options.SupportedUICultures = supportedCultures;
     options.DefaultRequestCulture = new RequestCulture(new CultureInfo("en-US"), 
        new CultureInfo("en-US"));
  });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env,
   ILoggerFactory loggerFactory)
{
      ...
      var supportedCultures = new List<CultureInfo>{
         new CultureInfo("en-US"),
         new CultureInfo("sl-SI"),
         new CultureInfo("de-DE"),
         new CultureInfo("hr-HR")
      };
      var requestLocalizationOptions = new RequestLocalizationOptions
      {
         SupportedCultures = supportedCultures,
         SupportedUICultures = supportedCultures,
         DefaultRequestCulture = new RequestCulture(new CultureInfo("en-US"), 
            new CultureInfo("en-US"))
       };
       app.UseRequestLocalization(requestLocalizationOptions);
}

这就是我在 ActionFilter 中改变 OnActionExecuting 内部文化的方式

actionContext.HttpContext.Response.Cookies.Append(
    CookieRequestCultureProvider.DefaultCookieName,
    CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
    new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) });
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;

我也尝试在我的控制器上执行此操作,但没有成功。

然后在我看来,我使用@inject IViewLocalizer Localizer 来显示带有@Localizer["Name"] 的本地化字符串。

我的资源位于文件夹 Resources/Views/ControllerName 中,如下所示:

  • 资源/视图/ControllerName/ViewName.en.resx
  • 资源/视图/ControllerName/ViewName.sl.resx
  • ...

无论我如何尝试改变文化,显示的字符串总是来自 .en 资源文件。 有什么我想念的吗?还有什么我应该做的吗?看来我遇到的问题是设置语言。根据文档,您应该使用Response.Cookies.Append 设置cookie,但我也尝试使用CultureInfo.CurrentCulture,因为Thread.CurrentThread.CurentCulture 不再可用。

我真的不知道我错过了什么。有什么想法吗?

【问题讨论】:

    标签: asp.net-core asp.net-core-mvc asp.net-core-1.0 asp.net-core-localization


    【解决方案1】:

    您可能遇到以下问题: https://github.com/aspnet/Mvc/issues/4692

    主要看评论:https://github.com/aspnet/Mvc/issues/4692#issuecomment-223671462

    总结:您可以在 MVC 中创建 Resource 过滤器来解决此问题:

    public class CultureSettingResourceFilter : IResourceFilter, IOrderedFilter
    {
        public int Order
        {
            get
            {
                return int.MinValue;
            }
        }
    
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            // By this time the response would already have been started, so do not try to modify the response
        }
    
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            var culture = httpContext.GetRouteValue("your-culture-key-name")?.ToString();
            // set your culture here
            CultureInfo.CurrentCulture = culture;
            CultureInfo.CurrentUICulture = culture;
        }
    }
    
    services.AddMvc(o =>
    {
        o.Filters.Add(new CultureSettingResourceFilter());
    });
    

    【讨论】:

    • 非常感谢。是的,如果我在 OnResourceExecuting 中硬编码一些本地化,我的本地化确实开始工作。我现在遇到的问题是获得想要的文化。我正在尝试从 url 中获取文化,例如localhost:5000/sl/otherStuff。有什么办法可以在 OnResourceExecuting 中获取它?
    • 使用过滤器时,您将可以访问当前请求的路由数据,因此您可以使用httpContext.GetRouteValue("culture-key-name")(您需要添加Microsoft.AspNetCore.Routing 命名空间才能看到GetRouteValueGetRouteData 扩展。
    • 非常感谢您的帮助。现在我测试了所有内容,我确认它有效。谢谢。
    • @KiranChalla 我正在尝试同样的事情,唯一的区别是我从数据库中提取资源,在登录页面上我有下拉列表,我想从中更改文化。那么我该怎么做呢?
    【解决方案2】:

    我对 i18n 进行了试验,当支持的文化与资源文件名中的文化匹配时,我的翻译可以正常工作

    var supportedCultures = new List<CultureInfo>{
         new CultureInfo("en-US"),
         new CultureInfo("sl-SI"),
         new CultureInfo("de-DE"),
         new CultureInfo("hr-HR")
      };
    

    更改您的资源文件名

    资源/视图/ControllerName/ViewName.sl.resx

    针对特定的语言文化

    资源/视图/ControllerName/ViewName.sl-SI.resx

    【讨论】:

    • 感谢您的时间和回复,但这并没有解决我的问题。
    【解决方案3】:

    在@Siim Haas 上编辑。
    效果很好。
    就我而言:我使用 LanguageViewLocationExpanderFormat.SubFolder

    在 ConfigureServices(IServiceCollection 服务)

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });
    
        services.AddMvc()
            .AddViewLocalization(
                Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.SubFolder,
                opts => { opts.ResourcesPath = "Resources"; }
            )
            .AddDataAnnotationsLocalization();
    
        services.Configure<RequestLocalizationOptions>(opts =>
        {
            var supportedCultures = new[]
            {
                new CultureInfo("en-AU"),
                new CultureInfo("en-GB"),
                new CultureInfo("en-US"),
                new CultureInfo("en"),
                new CultureInfo("zh-cn"),
                new CultureInfo("zh"),
            };
            opts.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("en-US");
            opts.SupportedCultures = supportedCultures;
            opts.SupportedUICultures = supportedCultures;
        });
    }
    

    在配置时(IApplicationBuilder 应用程序、IHostingEnvironment env、ILoggerFactory loggerFactory)

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseRequestLocalization();
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}");
        });
    }
    

    我的资源结构喜欢:

    {您的项目}/Resources/Views/{您的控制器}/ViewName.en-us.resx

    【讨论】:

      猜你喜欢
      • 2018-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-26
      • 2020-07-25
      • 1970-01-01
      相关资源
      最近更新 更多