Kendo控件场景下Remote数据注解前端验证未触发问题求助
问题现象
- 页面部署两个表单控件:
Speed为数值输入框,Speed unit为单位下拉选择框,控件展示效果如下:
- 业务校验规则:速度值和速度单位必须同时填写/同时为空,只要填了其中一个,另一个就是必填项。
- 采用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
相关产品推荐
相关产品推荐

