ASP.NET Core 2.0中RequiredAttribute的本地化

问题描述 投票:5回答:3

我在新的.NET Core项目中苦苦挣扎。我有2个项目:

  • 具有模型和数据注释的DataAccess项目(例如RequiredAttribute)
  • 具有MVC视图等的Web项目

我希望在一个地方全局本地化所有验证属性,以获得类似MVC 5的行为。这可能吗?

我不想为模型/视图等提供单独的语言文件。

使用SharedResources.resx文件和本地化的DataAnnotation消息时,Microsofts文档不是很清楚。

在MVC 5中我没有处理它。我只需要将语言环境设置为我的语言,一切都很好。

我尝试将ErrorMessageResourceName和ErrorMessageResourceType设置为DataAccess项目中的共享资源文件名“Strings.resx”和“Strings.de.resx”:

[Required(ErrorMessageResourceName = "RequiredAttribute_ValidationError", ErrorMessageResourceType = typeof(Strings))]

我还尝试将设置名称设为RequiredAttribute_ValidationError - 但它不起作用。

我已经在Startup.cs中添加了.AddDataAnnotationsLocalization() - 但似乎什么也没做。

我读过几篇文章,但我找不到它为什么不起作用的原因。

编辑:我到目前为止:

1.)LocService类

 public class LocService
    {
        private readonly IStringLocalizer _localizer;

        public LocService(IStringLocalizerFactory factory)
        {
            _localizer = factory.Create(typeof(Strings));
        }

        public LocalizedString GetLocalizedHtmlString(string key)
        {
            return _localizer[key];
        }
    }

2.)使用Strings.cs添加了文件夹“Resources”(带有虚拟构造函数的空类)

3.)添加了一个带有“RequiredAttribute_ValidationError”项的Strings.de-DE.resx文件

4.)修改了我的Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<MessageService>();
            services.AddDbContext<DataContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddSingleton<LocService>();
            services.AddLocalization(options => options.ResourcesPath = "Resources");
            services.AddMvc()
                .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver())
                .AddDataAnnotationsLocalization(
                    options =>
                    {
                        options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(Strings));
                    });

            services.Configure<RequestLocalizationOptions>(
                opts =>
                {
                    var supportedCultures = new List<CultureInfo>
                    {
                        new CultureInfo("de-DE"),
                    };

                    opts.DefaultRequestCulture = new RequestCulture("de-DE");
                    // Formatting numbers, dates, etc.
                    opts.SupportedCultures = supportedCultures;
                    // UI strings that we have localized.
                    opts.SupportedUICultures = supportedCultures;
                });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();

            app.UseRequestLocalization(locOptions.Value);
            app.UseStaticFiles();
            app.UseMvcWithDefaultRoute();
        }

我按照这里的说明操作,但它不起作用:https://damienbod.com/2017/11/01/shared-localization-in-asp-net-core-mvc/

请记住,我的模型保存在一个单独的项目中。

c# asp.net-core
3个回答
8
投票

正如@Sven在他对Tseng's answer的评论中指出的那样,它仍然要求你指定一个明确的ErrorMessage,这非常乏味。

问题来自于ValidationAttributeAdapter<TAttribute>.GetErrorMessage()用来决定是否使用提供的IStringLocalizer的逻辑。我使用以下解决方案来解决该问题:

  1. 创建一个使用默认IValidationAttributeAdapterProvider的自定义ValidationAttributeAdapterProvider实现,如下所示: public class LocalizedValidationAttributeAdapterProvider : IValidationAttributeAdapterProvider { private readonly ValidationAttributeAdapterProvider _originalProvider = new ValidationAttributeAdapterProvider(); public IAttributeAdapter GetAttributeAdapter(ValidationAttribute attribute, IStringLocalizer stringLocalizer) { attribute.ErrorMessage = attribute.GetType().Name.Replace("Attribute", string.Empty); if (attribute is DataTypeAttribute dataTypeAttribute) attribute.ErrorMessage += "_" + dataTypeAttribute.DataType; return _originalProvider.GetAttributeAdapter(attribute, stringLocalizer); } }
  2. Startup.ConfigureServices()中注册适配器在调用AddMvc()之前: services.AddSingleton<Microsoft.AspNetCore.Mvc.DataAnnotations.IValidationAttributeAdapterProvider, LocalizedValidationAttributeAdapterProvider>();

我更喜欢根据实际属性使用“更严格”的资源名称,因此上面的代码将查找“必需”和“DataType_Password”等资源名称,但这当然可以通过多种方式进行自定义。

如果您更喜欢基于属性的默认消息的资源名称,您可以改为:

attribute.ErrorMessage = attribute.FormatErrorMessage("{0}");

5
投票

我尝试将ErrorMessageResourceName和ErrorMessageResourceType设置为DataAccess项目中的共享资源文件名“Strings.resx”和“Strings.de.resx”:

   [Required(ErrorMessageResourceName = "RequiredAttribute_ValidationError", ErrorMessageResourceType = typeof(Strings))]

我还尝试将设置名称设为RequiredAttribute_ValidationError - 但它不起作用。

你是在正确的轨道上,但你不一定需要设置ErrorMessageResourceName / ErrorMessageResourceType属性。

我们可以在source codeValidationAttributeAdapter<TAttribute>中看到,使用_stringLocalizer verison的条件是当ErrorMessage不是nullErrorMessageResourceName / ErrorMessageResourceTypenull

换句话说,当你没有设置任何属性或只有ErrorMessage。所以一个普通的[Required]应该可以工作(参见source传递给基类构造函数的地方)。

现在,当我们查看DataAnnotations resource file时,我们看到名称设置为“RequiredAttribute_ValidationError”,值为“{0}字段是必需的”。这是默认的英文翻译。

现在,如果在“Strings.de-DE.resx”中使用带有德语翻译的“RequiredAttribute_ValidationError”(或者只是将Strings.resx作为后备),它应该与注释中更正的命名空间一起使用。

因此,使用上述配置和GitHub存储库中的字符串,您应该能够在没有额外属性的情况下使本地化工作。


1
投票

遗憾的是,在一个地方本地化数据属性的所有错误消息并不是那么简单!因为有不同类型的错误消息,

标准数据属性的错误消息:

[Required]
[Range]
[StringLength]
[Compare]
...etc.

ModelBinding的错误消息:

ValueIsInvalid
ValueMustNotBeNull
PropertyValueMustBeANumber
...etc.

和身份错误消息:

DuplicateEmail
DuplicateRoleName
InvalidUserName
PasswordRequiresLower
PasswordRequiresUpper
...etc

必须在启动文件中配置每个。还必须考虑Additionaly客户端验证。

您可以查看这些文章以获取更多详细信息,它包含GitHub上的实时演示和示例项目:

开发多元文化网络应用程序:http://www.ziyad.info/en/articles/10-Developing_Multicultural_Web_Application

本地化数据注释:http://www.ziyad.info/en/articles/16-Localizing_DataAnnotations

本地化ModelBinding错误消息:http://www.ziyad.info/en/articles/18-Localizing_ModelBinding_Error_Messages

本地化身份错误消息:http://www.ziyad.info/en/articles/20-Localizing_Identity_Error_Messages

和客户端验证:http://ziyad.info/en/articles/19-Configuring_Client_Side_Validation

希望能帮助到你 :)

© www.soinside.com 2019 - 2024. All rights reserved.