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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 17:48:11