使用DataAnnotations的[DataType(DataType.Currency)]模型验证自定义错误不生效问题
问题原因
- 你看到的系统默认提示是模型绑定阶段的类型转换校验抛出的,执行优先级高于你添加的DataAnnotations属性校验:你定义的
IznosPrihod是decimal值类型,当用户提交的内容无法被框架正常转换为decimal类型时,会直接触发系统默认的类型转换错误,此时你在Required、DataType上配置的ErrorMessage还没有被执行到。 [DataType(DataType.Currency)]本身仅用于控制字段的渲染格式、显示规则,并不负责输入内容的格式校验,所以即使类型转换成功,这个注解也不会抛出你设置的错误提示。
解决方案
方案1:全局修改数值类型转换的默认错误提示
如果所有数值字段的类型转换错误都可以用同一种自定义提示,直接在.NET的MVC配置中替换默认消息即可:.NET 6及以上版本在Program.cs中添加如下配置:
builder.Services.AddControllersWithViews() .AddMvcOptions(options => { // 替换数值类型转换失败的默认提示,{0}会自动替换为字段的Display名称 options.ModelBindingMessageProvider.SetValueMustBeANumberAccessor( fieldName => $"Molimo unesite ispravan format valute za polje {fieldName}!"); });
如果是.NET Framework版本的MVC,在Global.asax.cs的Application_Start方法中添加对应配置即可。
方案2:针对单字段自定义校验规则
如果只需要给这个货币字段单独设置校验规则,可以调整属性定义和注解:
将属性改为可空decimal?类型避免触发默认的类型转换校验,配合RegularExpression实现货币格式校验:
[Display(Name = "Iznos Prihoda")] [Required(ErrorMessage = "Molimo unesite iznos prihoda!")] [RegularExpression(@"^\d+(\,\d{1,2})?$", ErrorMessage = "Molimo unesite ispravni format valute!")] public decimal? IznosPrihod { get; set; }
正则可以根据你使用的货币分隔符调整,示例中用逗号做小数位分隔符,如需用点可以把正则里的
,换成.。
你也可以直接把属性定义为string类型,校验通过后在业务代码中手动转换为decimal使用,灵活度更高。
方案3:自定义校验属性
如果项目中有多处货币格式校验需求,可以继承ValidationAttribute编写统一的自定义校验属性,复用校验规则和错误提示。
内容的提问来源于stack exchange,提问作者Jogi6
相关产品推荐
相关产品推荐

