ABP模态框表单decimal字段验证语言不符、小数传值异常问题
decimal类型字段法语区本地化异常修复方案
验证提示始终为英文问题修复
该问题的根因是ASP.NET Core Tag Helper生成decimal类型绑定的input时,会将英文数值校验提示硬编码写入data-val-number属性,优先级高于jQuery Validate全局加载的法语语言包,且ABP动态加载模态框表单时会重置预加载的校验规则,单独引入message_fr.js无法覆盖属性上硬编码的文案。
修复步骤:
- 在ABP UI初始化完成回调中重写jQuery Validate数值校验规则,适配法语区逗号小数格式,同时配置全局默认校验文案:
abp.ui.on('initialized', function () { // 适配逗号作为小数分隔符的校验规则 $.validator.methods.number = function (value, element) { return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\s\d{3})+)?(?:,\d+)?$/.test(value); } $.validator.unobtrusive.adapters.addBool("number"); // 配置法语数值校验提示 $.extend($.validator.messages, { number: "Veuillez entrer un nombre valide." }); })
- 模态框表单加载完成后,统一更新所有数值输入框硬编码的校验提示,再重新解析表单验证规则:
// 模态框内容渲染完成回调中执行 function refreshFormValidation() { $('input[data-val-number]').each(function () { $(this).attr('data-val-number', "Veuillez entrer un nombre valide."); }) // 重新解析不唐突验证规则 $.validator.unobtrusive.parse('form'); }
小数传值后端接收为0问题修复
该问题的根因是ASP.NET Core默认模型绑定使用固定区域格式,仅识别.作为小数分隔符,法语区type="number"输入框提交时会自动将.转换为,,或用户输入逗号格式小数时,默认模型绑定解析失败会直接给字段赋值0,无显性报错。
修复需要前后端配合处理:
后端配置
- 在Program/Startup服务配置段,插入自定义decimal模型绑定器,同时兼容逗号、小数点两种分隔符:
builder.Services.AddControllersWithViews() .AddDataAnnotationsLocalization() .AddViewLocalization() .AddMvcOptions(options => { options.ModelBinderProviders.Insert(0, new FlexibleDecimalModelBinderProvider()); });
- 实现自定义模型绑定器逻辑:
public class FlexibleDecimalModelBinderProvider : IModelBinderProvider { public IModelBinder? GetBinder(ModelBinderProviderContext context) { return context.Metadata.ModelType == typeof(decimal) || context.Metadata.ModelType == typeof(decimal?) ? new FlexibleDecimalModelBinder() : null; } } public class FlexibleDecimalModelBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueResult == ValueProviderResult.None) return Task.CompletedTask; bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueResult); var rawValue = valueResult.FirstValue; if (string.IsNullOrWhiteSpace(rawValue)) return Task.CompletedTask; // 统一将逗号替换为小数点,兼容两种分隔符格式 rawValue = rawValue.Replace(',', '.'); if (decimal.TryParse(rawValue, NumberStyles.Number, CultureInfo.InvariantCulture, out var parsedValue)) { bindingContext.Result = ModelBindingResult.Success(parsedValue); } else { bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "Veuillez entrer un nombre valide."); } return Task.CompletedTask; } }
前端适配
- 表单提交前统一将所有数值输入框的逗号替换为小数点,规避浏览器number输入框的格式差异:
$('form').on('submit', function () { $(this).find('input[data-val-number]').each(function () { const currentVal = $(this).val(); if (currentVal) { $(this).val(currentVal.replace(',', '.')); } }) })
- 如需保留用户输入时显示逗号的本地化体验,可增加失焦格式化逻辑:用户输入完成失焦时自动将点转为逗号显示,提交时再转回点格式即可。
注意事项
- 不要给decimal字段加
[RegularExpression]特性限制数值格式,会覆盖自定义的校验规则。 - ABP框架默认未集成jQuery Validate全量法语翻译资源,手动在初始化阶段配置校验文案稳定性最高。
- 标记为
[HiddenInput]的decimal字段(如示例中的RateGeneral),前端赋值时需使用.作为小数分隔符,否则同样会出现模型绑定为0的问题。
内容的提问来源于stack exchange,提问作者ADeniel
相关产品推荐
相关产品推荐

