You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 10:09:17