ASP.NET字段验证异常:非正数校验失效及多小数位兼容问题
解决方案
1. 分离视图模型与数据传输对象(DTO)
将Razor页面提交用的ViewModel和其他平台接口接收用的DTO拆分,各自承担对应验证规则:
- ViewModel(页面提交专用):添加
[Range(0.01, double.MaxValue, ErrorMessage = "请输入大于0的数值")],强制用户提交的数值必须大于0。 - DTO(跨平台数据接收专用):仅保留必要的格式校验(如必填),不添加Range限制,允许接收0值。
示例代码:
// Razor页面提交用ViewModel public class AgnasLineViewModel { [Required(ErrorMessage = "此字段不能为空")] [Range(0.01, double.MaxValue, ErrorMessage = "请输入大于0的数值")] public decimal Amount { get; set; } // 优先用decimal类型,避免double浮点数精度丢失问题 } // 其他平台数据接收用DTO public class AgnasLineDto { [Required(ErrorMessage = "此字段不能为空")] public decimal Amount { get; set; } // 允许传入0值 }
2. 修复客户端验证精度异常
默认jQuery Validation的Range验证可能因JS浮点数精度问题,导致3位小数的非正数绕过校验,需自定义客户端验证规则:
步骤1:添加自定义验证脚本
在页面底部或_ValidationScriptsPartial.cshtml中加入以下代码:
$.validator.addMethod('strictgreaterthanzero', function (value, element) { const num = parseFloat(value); // 直接判断数值是否严格大于0,避免精度误差 return this.optional(element) || num > 0; }, '请输入大于0的数值'); // 将自定义规则绑定到非侵入式验证 $.validator.unobtrusive.adapters.add('strictgreaterthanzero', [], function (options) { options.rules['strictgreaterthanzero'] = true; options.messages['strictgreaterthanzero'] = options.message; });
步骤2:绑定到页面输入字段
在Razor页面的input元素上添加自定义验证属性:
<input asp-for="Amount" data-val-strictgreaterthanzero="请输入大于0的数值" />
3. 服务端兜底校验(可选)
为防止客户端验证被绕过,在页面提交的Action中补充校验逻辑:
public IActionResult OnPost(AgnasLineViewModel model) { if (!ModelState.IsValid) { return Page(); } // 兜底校验,确保数值严格大于0 if (model.Amount <= 0) { ModelState.AddModelError(nameof(model.Amount), "请输入大于0的数值"); return Page(); } // 转换为DTO进行后续业务处理 var dto = new AgnasLineDto { Amount = model.Amount }; // ... 业务逻辑代码 return RedirectToPage("./Success"); }
内容的提问来源于stack exchange,提问作者Maksio
相关产品推荐
相关产品推荐

