asp net core 2 中的 DataAnnotations 本地化

DataAnnotations localization in asp net core 2

我正在尝试实现这个:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-2.1#dataannotations-localization

我的代码:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
...
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization(options =>
    {
        options.DataAnnotationLocalizerProvider = (type, factory) =>
            factory.Create(typeof(SharedResource));
    });
...
}

SharedResource.cs

namespace MyProj.Classes
{
    /// <summary>
    /// Dummy class to group shared resources
    /// </summary>
    public class SharedResource
    {

    }
}

FooViewModel.cs

public class FooViewModel
{
    [Required(ErrorMessage = "EmailRequired")]
    [EmailAddress(ErrorMessage = "EmailIsNotValid")]
    [Display(Name = "Email")]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }
}

FooPage.cshtml

...
<input asp-for="Email" class="form-control">
<div class="invalid-feedback" style="display:block;">
    <span asp-validation-for="Email"></span>
</div>
...

我有资源文件Resources\SharedResource.resx

电子邮件 电子邮件
EmailIsNotValid 电子邮件字段不是有效的电子邮件地址。
EmailRequired 电子邮件字段是必需的。

不起作用,在编译或运行期间没有错误。它没有翻译,而是显示 'EmailIsNotValid' 或 'EmailRequired'。会出什么问题?

Duplicate of Localization of RequiredAttribute in ASP.NET Core 2.0 但没有标记答案,它隐藏在评论中。

Dummy SharedResource class 应该与 Web 应用程序 (startup.cs) 在同一个命名空间中。就我而言,我删除了“.classes”。文档不清楚。

更新: 对于与我一样的虚拟 classes,应用与文档中相同的文件名规则: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-2.1#resource-file-naming

Resources are named for the full type name of their class minus the assembly name. For example, a French resource in a project whose main assembly is LocalizationWebsite.Web.dll for the class LocalizationWebsite.Web.Startup would be named Startup.fr.resx. A resource for the class LocalizationWebsite.Web.Controllers.HomeController would be named Controllers.HomeController.fr.resx. If your targeted class's namespace isn't the same as the assembly name you will need the full type name. For example, in the sample project a resource for the type ExtraNamespace.Tools would be named ExtraNamespace.Tools.fr.resx.

另一种解决方法是将资源文件命名为 'Classes.SharedResource.resx' 或将其放在文件夹 Resources\Classes.