ASP.NET 7.0 Razor Pages中DataType与Range数据注解本地化失效问题
ASP.NET 7.0 Razor Pages 数据注解本地化问题解决
问题概述
在ASP.NET 7.0 Razor Pages应用中,数据注解的错误消息本地化对多数属性生效,但存在以下异常:
DataType属性对应的错误消息始终显示为英文- 非可空值类型字段(如
int YearGo)为空时,Range注解会触发与DataType相同的英文错误消息 - 使用
ErrorMessageResourceName和ErrorMessageResourceType属性对DataType注解做本地化配置无效
已配置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; }
Program.cs 核心配置
public static void Main(string[] args) { string culture = "it"; Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture); var builder = WebApplication.CreateBuilder(args); 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."))); 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(); // ... 其余中间件配置 app.UseRequestLocalization(); app.Run(); }
原因分析
DataType注解的本质:DataType本身不提供验证逻辑,页面显示的"Invalid date"等错误是模型绑定阶段的类型转换错误,而非DataType注解的验证错误,因此直接给DataType设置ErrorMessageResourceName不会生效。- 值类型空值绑定问题:非可空值类型(如
int YearGo)无法绑定空值,会触发默认的类型转换错误,显示英文消息,而非Range或Required注解的自定义错误。 - 资源文件配置不匹配:当前
DataAnnotationsLocalization指向的是SharedResource资源,而本地化错误消息存放在ValidationMessages资源文件中,导致无法读取对应本地化内容。
解决方案
1. 修正数据注解本地化的资源指向
修改AddDataAnnotationsLocalization的配置,将资源提供器指向ValidationMessages资源文件:
builder.Services.AddRazorPages() .AddDataAnnotationsLocalization(opts => { opts.DataAnnotationLocalizerProvider = (type, factory) => { var assemblyName = new AssemblyName(typeof(ValidationMessages).GetTypeInfo().Assembly.FullName!); return factory.Create(nameof(ValidationMessages), assemblyName.Name!); }; }) .AddViewLocalization();
2. 本地化模型绑定错误消息
在ValidationMessages.it.resx中添加模型绑定错误对应的键值对(示例):
| 键 | 意大利语值 |
|---|---|
| The field {0} must be a date. | Il campo {0} deve essere una data. |
| The field {0} must be a number. | Il campo {0} deve essere un numero. |
这些键是ASP.NET Core模型绑定错误的默认消息键,添加后会自动替换对应的英文错误。
3. 处理值类型空值问题
将非可空值类型改为可空类型,配合Required注解,让空值触发Required的本地化错误,而非类型转换错误:
[Display(Name = "Year go")] [Required(ErrorMessageResourceName = nameof(ValidationMessages.Required), ErrorMessageResourceType = typeof(ValidationMessages))] [Range(2000, 2100, ErrorMessageResourceName = nameof(ValidationMessages.Range), ErrorMessageResourceType = typeof(ValidationMessages))] public int? YearGo { get; set; } // 改为可空int
4. 确保资源文件的访问修饰符为Public
在资源文件的属性设置中,将“自定义工具”改为PublicResXFileCodeGenerator,并将“访问修饰符”设置为Public,确保代码能正确访问资源内容。
验证效果
完成上述修改后:
DataType对应的模型绑定错误会显示本地化后的消息- 空值字段会触发
Required的本地化错误,而非类型转换错误 Range等注解的本地化消息正常生效
内容的提问来源于stack exchange,提问作者steve fax
相关产品推荐
相关产品推荐

