如何在asp.net核心中以强类型方式获取资源字符串?

时间:2017-02-01 09:43:08

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

在以下程序中,为了获取资源字符串,我正在使用_localizer ["关于标题"]其中"关于标题"是一个神奇的字符串。如何避免使用这样的字符串?有任何强烈的打字方式吗?

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;

namespace Localization.StarterWeb.Controllers
{
    [Route("api/[controller]")]
    public class AboutController : Controller
    {
        private readonly IStringLocalizer<AboutController> _localizer;

        public AboutController(IStringLocalizer<AboutController> localizer)
        {
            _localizer = localizer;
        }

        [HttpGet]
        public string Get()
        {
            return _localizer["About Title"];
        }
    }
}

3 个答案:

答案 0 :(得分:8)

如果您尝试避免使用硬编码字符串(键)来查找本地化转换,则可以创建一个包含查找键的LocalizationKeys类。然后,您可以使用 C#6 nameof运算符。这将有助于减轻&#34;魔术弦&#34;。

的关注
public static class LocalizationKeys
{
    public const string AboutTitle = nameof(AboutTitle); // Note: this is "AboutTitle"

    // ... other keys here
}

然后你可以在任何地方消费它。其中一个好处是,因为它是类的成员,如果键更改,您可以使用常用的重构工具来安全地替换对它的所有引用,而不是尝试在&#34;魔术字符串&上执行全局字符串替换#34 ;.另一个好处是您在访问课程时可以使用intellisense。我想人们可以考虑这个&#34;强类型&#34;。

你这样消费它:

[Route("api/[controller]")]
public class AboutController : Controller
{
    private readonly IStringLocalizer<AboutController> _localizer;

    public AboutController(IStringLocalizer<AboutController> localizer)
    {
        _localizer = localizer;
    }

    [HttpGet]
    public string Get()
    {
        return _localizer[LocalizationKeys.AboutTitle];
    }
}

如果您真的希望使用 C#6 ,您也可以使用静态使用。这将允许您引用指定类型的成员。最后,对于简单的单线&#34;返回,我们可以使它们成为表达体。例如:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using static Localization.StarterWeb.LocalizationKeys; // Note: static keyword

namespace Localization.StarterWeb.Controllers
{
    [Route("api/[controller]")]
    public class AboutController : Controller
    {
        private readonly IStringLocalizer<AboutController> _localizer;

        public AboutController(IStringLocalizer<AboutController> localizer)
        {
            _localizer = localizer;
        }

        [HttpGet]
        public string Get() => _localizer[AboutTitle]; // Note: omission of qualifier
    }
}

答案 1 :(得分:3)

  1. 使用翻译创建资源文件(.resx)。例如,如果您要本地化AboutController,则类似于AboutController.String.resx

  2. 在编辑资源屏幕上,通过将Access Modifier从“无代码生成”更改为“公共”或“内部”,为资源文件启用代码生成。保存后,将为您的资源文件创建一个.Designer.cs类。对于资源文件中的每个键,它将包含一个静态属性。不要手动修改生成的类。每次修改.resx后,它将自动重新生成。

enter image description here

  1. 在控制器中使用生成的设计器类获取翻译后的文本(在这种情况下,无需字符串本地化器):

    [HttpGet]
    public string Get()
    {
        return AboutController_Strings.AboutTitle;
    }
    

    这也可以使用using static技巧:

    using static Localization.StarterWeb.AboutController_Strings;
    
    //(...)
    
    [HttpGet]
    public string Get()
    {
        return AboutTitle;
    }
    

    或者,您可以将其与ASP的本地化程序一起使用。在这种特定情况下,这不会增加任何值,但是对于IHtmlLocalizer很有用,因为它将为您html逃逸这些值。

    [HttpGet]
    public string Get()
    {
        return _localizer[nameof(AboutTitle)];
    }
    

为什么这比公认的答案更好?这样,您无需手动创建和维护所有带有内部const字符串的类似LocalizationKeys的类。 (在较大的项目中,将有成百上千的项目!)生成的.Designer.cs类将包含资源文件中的所有键。而已。没什么。如果您从资源填充中删除某些内容,则将其从生成的代码中删除,并且无论使用了delete属性的位置在代码中都会产生编译错误。如果在资源文件中添加一些内容,它将在保存资源文件时自动生成一个新属性,该属性将显示在代码完成中。

这是一种更为传统的方法,最初是通过WinForms完成的。在Microsoft的documentation for localizing ASP.NET Core应用中,有一个简短的解释,说明了为什么他们使用IStringLocalizer添加了新方法:硬编码转换字符串使您的工作流程更快。无需维护其他东西,直到需要为止。

  

对于许多开发人员而言,没有默认语言.resx文件并且仅包装字符串文字的新工作流程可以减少本地化应用程序的开销。其他开发人员将更喜欢传统的工作流程,因为它可以更轻松地处理更长的字符串文字,并更轻松地更新本地化的字符串。

答案 2 :(得分:1)

仅针对今天看到此内容的人:我不知道 Microsoft 何时添加此内容,但在 .Net 5.0 中,您可以简单地对配置功能执行此操作:

app.UseRequestLocalization(options =>
        {
            var supportedCultures = new[]
            {
                new CultureInfo("en"),
                new CultureInfo("de")
            };
            options.DefaultRequestCulture = new RequestCulture("en", "en");
            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;
        });

并且只需将普通资源文件与静态生成的类一起使用,而无需 IStringLocalizer 或类似的东西。 我不知道,你是否可以简单地在 razorpages 或类似的东西中使用它们,但它在普通的“webapi”项目中按预期工作。