ASP.NET Core中Decimal参数无法绑定小数,控制器接收值为0问题
问题分析与解决
问题场景
定义了如下AgeDto模型:
public class AgeDto { public long Id { get; set; } [Required] [Precision(2, 1)] public decimal LowAge { get; set; } [Precision(2, 1)] public decimal? HighAge { get; set; } }
对应的Razor表单代码:
@model AgeDto <form class="form-account" method="post" asp-action="Index" asp-controller="ages"> <div class="d-inline-block w-25"> <div class="label-form "> From</div> <div> <input asp-for="LowAge" type="text" class=" w-50"> <span asp-validation-for="LowAge" class="text-danger star-red"></span> </div> </div> <div class="d-inline-block w-25"> <div class="label-form "> To</div> <div> <input asp-for="HighAge" type="text" class=" w-50"> <span asp-validation-for="HighAge" class="text-danger star-red"></span> </div> </div> <div class="d-inline-block w-25"> <div class="d-inline-block px-3"> <input asp-for="Id" type="hidden" /> <input class="btn btn-primary btn-register" type="submit" value="Register" /> </div> </div> </form>
控制器接收代码:
[HttpPost] public async Task<IActionResult> Index(AgeDto agesDto) { // 业务逻辑 }
输入1.5、2.5这类带小数的数值时,控制器中agesDto的LowAge值为0,HighAge值为null,无法正确获取输入的小数数值。
原因
核心问题是ASP.NET Core模型绑定的区域文化不匹配:
- 默认情况下,模型绑定会使用服务器的系统区域文化解析数值。如果服务器区域文化以逗号(
,)作为小数点分隔符(如欧洲部分地区),而你输入的是点(.)作为分隔符,模型绑定会解析失败,最终给值类型decimal赋值默认值0,可空decimal?则为null。 - 注意:
[Precision]特性仅用于EF Core配置数据库列的精度和小数位数,对模型绑定的数值解析没有作用。
解决方案
方法1:全局配置区域文化
在Program.cs中设置应用使用支持点作为小数点的区域文化(如en-US或zh-CN):
var builder = WebApplication.CreateBuilder(args); // 配置请求区域文化 builder.Services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { "en-US", "zh-CN" }; options.SetDefaultCulture("en-US") .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures); }); var app = builder.Build(); // 启用区域文化中间件 app.UseRequestLocalization(); // 其他中间件配置...
方法2:为模型属性添加格式化特性
在AgeDto的属性上添加[DisplayFormat],强制指定数值解析格式:
public class AgeDto { public long Id { get; set; } [Required] [Precision(2, 1)] [DisplayFormat(DataFormatString = "{0:F1}", ApplyFormatInEditMode = true)] public decimal LowAge { get; set; } [Precision(2, 1)] [DisplayFormat(DataFormatString = "{0:F1}", ApplyFormatInEditMode = true)] public decimal? HighAge { get; set; } }
方法3:修改输入框类型
将输入框类型改为number并指定step属性,既符合数值输入规范,也能辅助模型绑定正确解析:
<input asp-for="LowAge" type="number" step="0.1" class="w-50"> <input asp-for="HighAge" type="number" step="0.1" class="w-50">
内容的提问来源于stack exchange,提问作者nnmmss
相关产品推荐
相关产品推荐

