DataType 和 Range 数据批注不会本地化错误消息

The DataType and Range data annotations do not localize the error message

提问人:steve fax 提问时间:10/31/2023 最后编辑:steve fax 更新时间:11/11/2023 访问量:123

问:

我不明白为什么在 asp.net 7.0 剃刀页面应用程序中,数据注释错误消息的本地化适用于所有属性,但“DataType”属性除外,其中显示的错误消息始终是英文的。

当字段为空时,“Range”属性也存在同样的问题,您会收到相同的“DataType”错误消息。

此外,使用 ErrorMessageResourceName 和 ErrorMessageResourceType 属性也无法进行本地化。

有两个资源文件 ValidationMessages.resx 和 ValidationMessages.it.resx,这两个文件都包含所有错误消息。

数据模型的一部分:

    [Display(Name = "Year go")]
    [Required(ErrorMessage = "Required")]
    [Range(2000, 2100, ErrorMessage = "Range")]
    //[Range(2000, 2100, ErrorMessageResourceName = nameof(ValidationMessages.Range), ErrorMessageResourceType = typeof(ValidationMessages))]
    public int YearGo { get; set; }

    //[DataType(DataType.Date, ErrorMessage = "DataType")]
    [DataType(DataType.Date, ErrorMessageResourceName = nameof(ValidationMessages.DataType), ErrorMessageResourceType = typeof(ValidationMessages))]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 10, ErrorMessage = "Range")]
    //[DataType(DataType.Currency, ErrorMessage = "DataType")]
    [DataType(DataType.Currency, ErrorMessageResourceName = nameof(ValidationMessages.DataType), ErrorMessageResourceType = typeof(ValidationMessages))]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal? Price { get; set; } 

程序:

public static void Main(string[] args)
{
    string culture = "it";
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);

    var builder = WebApplication.CreateBuilder(args);

    // Add services to the container.
    builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

    var supportedCultures = new[] { new CultureInfo("it"), new CultureInfo("en-US") };
    builder.Services.Configure<RequestLocalizationOptions>(options =>
    {
        options.DefaultRequestCulture = new RequestCulture(culture);
        options.SupportedCultures = supportedCultures;
        options.SupportedUICultures = supportedCultures;
    });

    builder.Services.AddDbContext<OWsefaWebContext>(options =>
        options.UseSqlServer(builder.Configuration.GetConnectionString("OWsefaWebContext") ?? throw new InvalidOperationException("Connection string 'OWsefaWebContext' not found.")));

    // Add services to the container.
    builder.Services.AddRazorPages()
        .AddDataAnnotationsLocalization(opts =>
        {
            opts.DataAnnotationLocalizerProvider = (type, factory) =>
            {
                var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName!);
                return factory.Create(nameof(SharedResource), assemblyName.Name!);
            };
        })
        .AddViewLocalization();


    var app = builder.Build();

    using (var scope = app.Services.CreateScope())
    {
        var services = scope.ServiceProvider;
        DataInitializer.Initialize(services);
    }

    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();
    app.MapRazorPages();

    app.UseRequestLocalization();

    app.Run();
}

屏幕截图:enter image description here

asp.net-core razor-pages 数据批注

评论

0赞 Jason Pan 11/1/2023
我还没有看到您正在使用 ,所以您能否检查示例代码RequestLocalizationOptions
0赞 steve fax 11/2/2023
嗨,Jason,感谢您的回复,我按照您的指示进行了更改,但我仍然收到未本地化的 DataType 消息。我更新了帖子代码并添加了屏幕截图。
0赞 Jason Pan 11/3/2023
此错误消息由内置模型验证引发,它不会执行您的方法。DataType and Range data annotations
0赞 Jason Pan 11/3/2023
我们可以考虑使用 ModelBindingMessageProvider 来处理这个问题。
0赞 Jason Pan 11/3/2023
由于没有可以重现该问题的存储库,因此您需要自己尝试一下。如果你能为我们创建一个全新的项目,别忘了隐藏敏感信息,tks~。

答:

2赞 Roberto Ferraris 11/11/2023 #1

我检查了您的代码,我意识到问题是系统返回的错误消息不是来自 ,而是来自 .NET 的绑定系统。DataTypeAttribute

绑定系统的消息派生自 DefaultModelBindingMessageProvider ,您可以设置各种方法来提供自定义错误消息。

您可以在方法中设置消息,这是我在您的代码中所做的更改,以使其与提供的资源一起使用。AddMvcOptions

builder.Services.AddRazorPages()
    .AddDataAnnotationsLocalization(opts =>
    {
        opts.DataAnnotationLocalizerProvider = (type, factory) =>
        {
            var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName!);
            return factory.Create(nameof(SharedResource), assemblyName.Name!);
        };
        
    })
    .AddViewLocalization()
    .AddMvcOptions(options => {
        options.ModelBindingMessageProvider.SetValueMustBeANumberAccessor(
            (arg) => {
                return string.Format(CultureInfo.CurrentCulture, Resources.SharedResource.Message_DataType, arg);
        });
    });

出于某些原因,您需要指定当前区域性才能使用意大利语资源。string.Format