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

Kendo控件场景下Remote数据注解前端验证未触发问题求助

问题现象
  • 页面部署两个表单控件:Speed为数值输入框,Speed unit为单位下拉选择框,控件展示效果如下:
    Speed与速度单位控件展示
  • 业务校验规则:速度值和速度单位必须同时填写/同时为空,只要填了其中一个,另一个就是必填项。
  • 采用ASP.NET Core自带的Remote远程验证特性实现规则,但前端始终不触发校验,检查DOM发现验证相关属性已经正常生成,提交表单时无校验提示,异常效果如下:
    验证未触发异常效果
现有代码

ViewModel 配置

[AbpDisplayName(OE_TenantConsts.LocalizationSourceName, "idb_Incident.Speed")]
[Range(0.0, double.MaxValue, ErrorMessage = "Please enter a value of {1} or more")]
[Remote(action: "VerifySpeedAndUnit", controller: "Event", AdditionalFields = nameof(SpeedUnitId))]
public decimal? Speed { get; set; }

[AbpDisplayName(OE_TenantConsts.LocalizationSourceName, "idb_Incident.SpeedUnitId")]
[Remote(action: "VerifySpeedAndUnit", controller: "Event", AdditionalFields = nameof(Speed))] 
public int? SpeedUnitId { get; set; }

后端验证接口

Event控制器下的校验方法:

[AcceptVerbs("GET", "POST")]
[AllowAnonymous]
public IActionResult VerifySpeedAndUnit(decimal? speed, int? speedUnitId)
{
    if ((speed.HasValue && speedUnitId == DropdownConstants.DefaultSelectedSpeedUnitId) || (speed.HasValue && speedUnitId == null))
    {
        return Json("When entering a speed, you need to select the speed scale as well.");
    }

    if (speedUnitId != DropdownConstants.DefaultSelectedSpeedUnitId && speed.HasValue && speedUnitId != null)
    {
        return Json("When selecting a speed scale, you need to enter a speed value as well.");
    }

    return Json(true);
}

Speed字段Kendo控件代码

<div class="mb-5 col-md-6 idb_Incident_Speed">
    @Html.LabelFor(model => model.Speed, htmlAttributes: new { @class = "control-label col-12" })
    <div class="col-12">
        <kendo-numerictextbox deferred="true" for="Speed"
                              format="#.##"
                              min="0"
                              name="Speed"
                              decimals="2"
                              placeholder="Enter Speed at time of Incident">
        </kendo-numerictextbox>

        @Html.ValidationMessageFor(model => model.Speed, "", new { @class = "text-danger" })
    </div>
</div>
问题原因与修复方案

1. 延迟初始化脚本未渲染

Kendo控件设置deferred="true"后不会直接输出初始化脚本,必须在所有Kendo控件声明完成后(通常放在页面底部或Layout脚本区域)调用脚本渲染方法,否则控件不会完成初始化,jQuery验证无法识别控件绑定的验证规则:

@Html.Kendo().DeferredScripts()

2. 后端验证逻辑写反

当前第二个判断分支不符合业务规则:只有选择了速度单位(speedUnitId不为null、不等于默认空选项值)但速度值为空时,才需要提示填写速度,现有代码判断两个值都存在时报错,逻辑完全颠倒,修正后的代码如下:

[AcceptVerbs("GET", "POST")]
[AllowAnonymous]
public IActionResult VerifySpeedAndUnit(decimal? speed, int? speedUnitId)
{
    // 填了速度没选单位
    if (speed.HasValue && (speedUnitId == null || speedUnitId == DropdownConstants.DefaultSelectedSpeedUnitId))
    {
        return Json("When entering a speed, you need to select the speed scale as well.");
    }
    // 选了单位没填速度
    if (speedUnitId != null && speedUnitId != DropdownConstants.DefaultSelectedSpeedUnitId && !speed.HasValue)
    {
        return Json("When selecting a speed scale, you need to enter a speed value as well.");
    }

    return Json(true);
}

3. 关联字段变化时未触发联动校验

Remote验证默认只在当前字段值变化、或者表单提交时触发,AdditionalFields配置仅负责提交验证时附带关联字段的值,不会在关联字段变化时自动触发当前字段的验证,需要加前端JS做联动触发:

$(function(){
    // 速度变化时触发单位字段验证
    $("#Speed").on("change", function(){
        $("form").validate().element("#SpeedUnitId");
    });
    // 单位变化时触发速度字段验证
    $("#SpeedUnitId").on("change", function(){
        $("form").validate().element("#Speed");
    });
})

4. 检查客户端验证脚本引用

确认页面/全局Layout中已经引用了客户端验证必须的基础脚本,缺失则Remote验证完全无法运行:

<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:18:19