【问题标题】:How to properly use resource files with string localizer in .NET Core 3.1?如何在 .NET Core 3.1 中正确使用带有字符串本地化器的资源文件?
【发布时间】:2020-10-04 13:18:52
【问题描述】:

我有一个项目,我在其中使用资源文件来存储一些文本,我也在尝试使用 StringLocalizer 从资源文件中获取所需的消息。我已经在 Startup 类中配置了本地化设置,如下所示:

internal static class LocalizationConfiguration
{
    private const string ResourcesPath = "Resources";
    private const string DefaultCulture = "en-US";

    internal static IServiceCollection ConfigureLocalizationSettings(this IServiceCollection services) =>
        services
            .AddLocalization(options =>
                options.ResourcesPath = ResourcesPath);

    internal static IApplicationBuilder UseRequestLocalizationMiddleware(this IApplicationBuilder builder) =>
        builder
            .UseRequestLocalization(new RequestLocalizationOptions
            {
                DefaultRequestCulture = new RequestCulture(DefaultCulture),
                SupportedCultures = new List<CultureInfo>
                {
                    new CultureInfo(DefaultCulture)
                }
            });
}

我的解决方案由几个项目组成。我需要在包含我的业务逻辑的项目中使用 StringLocalizer - xxx.Handlers。我还创建了一个名为 xxx.Resources 的项目,用于存储包含两个目录的资源:

这是我的 UserMessages 类(它是空的,虚拟类,跟在 https://docs.microsoft.com/pl-pl/aspnet/core/fundamentals/localization?view=aspnetcore-3.1 后面):

public class UserMessages
{
}

我将 StringLocalizer 注入到我的命令处理程序中,然后像下面这样使用它(UserConstants.UserNotFoundMessageKey 没问题):

var userEntity = await _userRepository.GetUserByIdAsync(command.UserId);

if (userEntity is null)
{
    var message = _stringLocalizer[UserConstants.UserNotFoundMessageKey];
    var statusCode = (int) HttpStatusCode.NotFound;
                
    throw new CommandException(message, statusCode);
}

问题是,我的消息没有以正确的方式本地化,表达式“_stringLocalizer[UserConstants.UserNotFoundMessageKey]”实际上返回的是 UserNotFoundMessageKey 的值,而不是位于资源文件中的消息。我究竟做错了什么??如何正确本地化这些消息?

【问题讨论】:

    标签: c# asp.net-core .net-core


    【解决方案1】:

    这是一个关于如何在单独的项目中创建共享资源的完整工作解决方案:

    在 ProjectA 中(在我的解决方案中是 SharedResource3_1):

    1.使用UserMessages类创建Shared文件夹并使用Shared.UserMessages.en-US.resx文件创建Resources文件夹(不知道为什么要创建Shared.UserMessages.en-US.Designer.cs,但它似乎没有用):

    UserMessages.cs:

    namespace SharedResource3_1.Shared
    {
        public class UserMessages
        {
        }
    }
    

    Shared.UserMessages.en-US.resx:

    在 ProjectB 中(在我的解决方案中是 MvcCore3_1):

    1.将项目引用添加到ProjectA:

    Right-click ProjectB Dependencies 并选择 Add Project Reference 然后选择 ProjectA:

    然后你可以得到如下的参考:

    2.Startup.cs:

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
    
            //add this...
            LocalizationConfiguration.ConfigureLocalizationSettings(services);
        }
       
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //add this...
            LocalizationConfiguration.UseRequestLocalizationMiddleware(app);
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
    
            app.UseAuthorization();
    
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
    
    internal static class LocalizationConfiguration
    {
        private const string ResourcesPath = "Resources";
        private const string DefaultCulture = "en-US";
    
        internal static IServiceCollection ConfigureLocalizationSettings(this IServiceCollection services) =>
            services
                .AddLocalization(options =>
                    options.ResourcesPath = ResourcesPath);
    
        internal static IApplicationBuilder UseRequestLocalizationMiddleware(this IApplicationBuilder builder) =>
            builder
                .UseRequestLocalization(new RequestLocalizationOptions
                {
                    DefaultRequestCulture = new RequestCulture(DefaultCulture),
                    SupportedCultures = new List<CultureInfo>
                    {
                    new CultureInfo(DefaultCulture)
                    }
                });
    }
    

    3.HomeController:

    using SharedResource3_1.Shared;  //add the reference for the UserMessages in ProjectA
    
    public class HomeController : Controller
    {
        private readonly IStringLocalizer<UserMessages> _stringLocalizer;
        public HomeController(IStringLocalizer<UserMessages> stringLocalizer)
        {
            _stringLocalizer = stringLocalizer;
        }
    
        public IActionResult Index()
        {
            ViewBag.data = _stringLocalizer["cześć"]; //the key name should be the Name in your resx file...
            return View();
        }
    }
    

    结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-02
      • 1970-01-01
      • 2015-06-13
      • 2017-01-14
      相关资源
      最近更新 更多