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

ASP.NET Core视图表单double类型属性绑定失败问题求助

问题:ASP.NET Core中捷克地区数值绑定的格式验证问题

在ASP.NET Core视图表单中输入带小数点的double/decimal值时,捷克地区无论用点(.)还是逗号(,)都会报错:输入1.5提示值无效,输入1,5提示字段必须是数字,值无法绑定到对应属性。


控制器代码

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create([Bind("Id,Name,Type,ApiId,Amount,InvestedMoney")] CommodityDto commodity)
{
    if (ModelState.IsValid)
    {
        portfolioCommodityManager.Add(commodity);
        return RedirectToAction(nameof(Index));
    }

    return View(commodity);
}

属性定义

public double Amount { get; set; }

视图代码

<label asp-for="Amount" class="control-label fw-bold"></label>
<input asp-for="Amount" class="form-control" />
<span asp-validation-for="Amount" class="text-danger"></span>

已尝试但无效的配置

services.Configure<RequestLocalizationOptions>(options =>
{
    options.DefaultRequestCulture = new RequestCulture("cs-CZ");
});
[DisplayFormat(DataFormatString = "{0:0.0}", ApplyFormatInEditMode = true)]
public double Amount { get; set; }

解决方案

1. 完善区域化配置(服务器端)

仅设置默认文化不足以生效,需完整配置支持的文化并确保中间件顺序正确。在Program.cs/Startup.cs中修改:

var supportedCultures = new[] { new CultureInfo("cs-CZ") };
app.UseRequestLocalization(new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture("cs-CZ"),
    SupportedCultures = supportedCultures,
    SupportedUICultures = supportedCultures
});

注意:UseRequestLocalization需放在UseRouting、UseAuthorization等中间件之前。

2. 同步客户端验证的区域化规则

ASP.NET Core默认客户端验证使用en-US格式,需引入全球化验证脚本并配置捷克文化:

  • 视图中添加依赖脚本:
    <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
    <script src="~/lib/cldrjs/dist/cldr.min.js"></script>
    <script src="~/lib/globalize/dist/globalize.min.js"></script>
    <script src="~/lib/jquery-validation-globalize/jquery.validate.globalize.min.js"></script>
    
  • 加载捷克地区的CLDR数据并设置客户端文化:
    <script>
        $.when(
            $.getJSON("/lib/cldr-data/main/cs-CZ/numbers.json"),
            $.getJSON("/lib/cldr-data/supplemental/likelySubtags.json"),
            $.getJSON("/lib/cldr-data/supplemental/numberingSystems.json")
        ).then(function () {
            return [].slice.apply(arguments).map(function (result) {
                return result[0];
            });
        }).then(Globalize.load).then(function () {
            Globalize.locale("cs-CZ");
        });
    </script>
    

可通过NuGet包CldrData获取CLDR数据文件。

3. 优化属性格式化标注

在属性上同时添加[DataType]和[DisplayFormat],确保编辑模式下格式生效:

[DataType(DataType.Number)]
[DisplayFormat(DataFormatString = "{0:N1}", ApplyFormatInEditMode = true)]
public double Amount { get; set; }

4. 自定义模型绑定器(兜底方案)

若上述方法仍无效,可自定义绑定器强制用捷克文化解析数值:

public class CzechNumberModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));

        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == ValueProviderResult.None)
            return Task.CompletedTask;

        bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
        var value = valueProviderResult.FirstValue;

        if (string.IsNullOrEmpty(value))
            return Task.CompletedTask;

        if (double.TryParse(value, NumberStyles.Any, new CultureInfo("cs-CZ"), out var result))
        {
            bindingContext.Result = ModelBindingResult.Success(result);
        }
        else
        {
            bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, $"字段 {bindingContext.ModelName} 必须是有效的数字。");
        }

        return Task.CompletedTask;
    }
}

在属性上注册绑定器:

[ModelBinder(BinderType = typeof(CzechNumberModelBinder))]
public double Amount { get; set; }

内容的提问来源于stack exchange,提问作者Tsko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 06:31:00