ASP.NET Core MVC输入小数提交后变为整数的问题排查
问题解决:ASP.NET Core MVC中提交小数丢失小数点的问题
问题根源分析
- Range特性类型不匹配:模型
Transaction的Value字段是decimal类型,但[Range(0, int.MaxValue)]用了整数类型的上限,这会干扰模型绑定对小数的解析逻辑。 - Number输入框默认限制:
<input type="number">默认step="1",仅允许整数输入,即便手动输入小数点,部分浏览器或模型绑定器也可能无法正确识别。 - 文化差异导致解析错误:若服务器默认文化使用逗号作为小数点分隔符,输入的
1.99会被当成199(点号被识别为千位分隔符)。
分步解决方案
1. 修正模型的Range特性
将Range特性的上限改为decimal.MaxValue,匹配字段的decimal类型:
public class Transaction { // ... 其他字段 [Range(0, decimal.MaxValue, ErrorMessage = "The value must be positive.")] [DataType(DataType.Currency)] [Required] public decimal Value { get; set; } // ... 其他字段 }
2. 配置Number输入框支持小数
修改HTML中的Value输入框,添加step="0.01"(适配货币场景的两位小数)和min="0":
<label>Value</label> <input type="number" placeholder="Value" asp-for="Transaction.Value" step="0.01" min="0"> <span asp-validation-for="Transaction.Value" class="text-danger"></span>
该设置会强制浏览器允许输入小数,且提交时正确传递格式。
3. 统一模型绑定的文化(可选)
若服务器文化与输入格式不匹配,在Program.cs中配置全局文化或模型绑定的不变文化:
// .NET 6+ Program.cs var builder = WebApplication.CreateBuilder(args); // 设置全局文化为en-US(使用点号作为小数点) var cultureInfo = new System.Globalization.CultureInfo("en-US"); System.Globalization.CultureInfo.DefaultThreadCurrentCulture = cultureInfo; System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = cultureInfo; // 配置MVC模型绑定 builder.Services.AddControllersWithViews() .AddMvcOptions(options => { options.ModelBindingMessageProvider.SetValueMustBeANumberAccessor(_ => "请输入有效的数字"); }) .AddJsonOptions(options => { options.JsonSerializerOptions.Culture = System.Globalization.CultureInfo.InvariantCulture; });
4. 移除控制器冗余代码
删除控制器中无用的重复解析代码:
// 移除这两行无意义的代码 decimal transactionValue = transaction.Value; transactionValue = decimal.Parse(transactionValue.ToString());
验证
修改完成后,输入1.99提交,控制器中transaction.Value将正确获取到1.99而非199。
内容的提问来源于stack exchange,提问作者Hiasd
相关产品推荐
相关产品推荐

