ASP.NET Core 继承ViewModel时数据注解资源本地化不生效
问题根本原因
这个问题和类继承机制无关,核心原因是你对数据验证特性的用法直接绕过了框架的本地化管线:
- 你在
[Required]、[RegularExpression]等特性上显式给ErrorMessage属性赋值了硬编码的固定字符串。数据注解验证的默认逻辑是:只要开发者手动指定了ErrorMessage的值,就直接使用该字符串作为错误提示,完全跳过本地化资源查找流程。 - 你项目中其他模块本地化正常,是因为那些模块没有手动硬编码错误消息,走了框架默认的资源查找逻辑,和继承、子类重写没有关系。
你观察到所有继承基类的视图模型验证消息都不生效,只是因为基类里的验证特性统一写了硬编码错误文本,不是继承机制导致的异常。
修复方案
移除所有验证特性上硬编码的ErrorMessage赋值,让框架接管验证消息的本地化查找,根据你的项目结构可以选两种实现方式:
方案1:全局共享验证资源(推荐,适合多模型复用提示文本的场景)
- 创建全局验证消息资源文件,例如在
Resources目录下新建ValidationMessages.resx(默认语言,通常是英文)、ValidationMessages.zh-CN.resx(中文资源),在资源中添加对应提示文本的键值对:资源键 对应提示 StatedDates_Required 请填写标注日期 StatedDates_RegularExpression 标注日期格式无效,请使用dd.MM.yyyy格式 CoordinatorFullName_Required 请选择对接人 WorkingPlan_Required 请填写工作计划 - 在应用启动配置中注册数据注解本地化,指定使用全局共享资源:
// Program.cs 中的服务注册部分 builder.Services.AddControllersWithViews() .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (_, factory) => factory.Create(typeof(ValidationMessages)); });
- 删除所有验证特性上的
ErrorMessage = "xxx"硬编码内容,框架会自动按照{属性名}_{验证特性名}的规则匹配资源键,自动输出对应语言的提示文本。你也可以手动指定ErrorMessage = nameof(ValidationMessages.对应资源键)来显式绑定资源项。
方案2:按视图模型拆分独立资源
如果你希望每个视图模型的资源文件和模型自身关联维护,不需要全局共享,可以在注册数据注解本地化时不指定共享资源类型,框架会自动按照模型类型查找对应路径的资源文件:
- 基类
ApplicationVM对应资源路径Resources/ViewModels/ApplicationVM.resx、Resources/ViewModels/ApplicationVM.zh-CN.resx - 子类
RemoteWorkingApplicationVM对应资源路径Resources/ViewModels/RemoteWorkingApplicationVM.resx、Resources/ViewModels/RemoteWorkingApplicationVM.zh-CN.resx - 资源键同样遵循
{属性名}_{验证特性名}的命名规则,基类定义的属性对应的验证消息,可以放在基类资源文件中,也可以在子类资源文件中重写覆盖。
注意事项
如果使用按模型拆分资源的方式,对于基类定义的属性,框架查找资源时会以当前实际调用的子类类型为基准,如果找不到对应键会回退到基类资源,最后回退到默认语言文本,不会出现继承导致的资源找不到问题。
内容的提问来源于stack exchange,提问作者Intolighter
相关产品推荐
相关产品推荐

