ASP.NET Core自定义验证属性未触发,求排查问题原因
ASP.NET Core自定义验证属性未生效问题排查
我正在学习ASP.NET Core自定义验证属性,编写了一个简单示例但验证未生效。提交表单时lastName字段未触发自定义验证,相关代码如下:
Model
public class Employee { public int? ID { get; set; } [MinLength(2)] [Remote(action: "VerifyNameExists",controller:"Employee")] public string Name { get; set; } [LastNameValid] public string? lastname { get; set; } public decimal? Salary { get; set; } }
View
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script> <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script> <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script> <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script> <script src="~/lib/jquery-validation/dist/additional-methods.min.js"></script> <script src="~/lib/jquery-validation/dist/additional-methods.js"></script> <a href="~/lib/jquery/dist/jquery.min.map">~/lib/jquery/dist/jquery.min.map</a> <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/jquery/dist/jquery.js"></script> @model Employee <div class="container"> <h1>Create Employee</h1> <div class="row"> <div class="col-sm-8"> <form class="d-grid form-control-sm" asp-controller="Employee" asp-action="Create" method="post"> <div class="form-group row"> <input class="col-sm-4" asp-for="ID" placeholder="ID" /> <span asp-validation-for="ID" style="color:red"></span> </div> <br /> <div class="form-group row"> <input type="text" class="col-sm-4" asp-for="Name" placeholder="First Name"/> <span asp-validation-for="Name" style="color:red"></span> </div> <br /> <div class="form-group row"> <input type="text" class="col-sm-4" asp-for=lastname placeholder="Last Name"/> <span asp-validation-for=lastname style="color:red"></span> </div> <br /> <br/> <input class="btn btn-primary col-sm-4" type="submit" name="Submit" value="Submit" /> </form> </div> </div> </div> @section Scripts { <partial name="_ValidationScriptsPartial"></partial> }
Controller
public IActionResult Create() { return View(); } [HttpPost] public IActionResult Create(Employee emp) { if (!ModelState.IsValid) { return View(); } return RedirectToAction("Index",emplist); }
自定义验证属性类
using System.ComponentModel.DataAnnotations; namespace MVCDemo { public class LastNameValidAttribute : ValidationAttribute { protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { if (value == "abc") { return new ValidationResult("not allowed"); } return ValidationResult.Success; } } }
问题排查与修复方案
修正自定义验证逻辑的类型匹配问题
原代码中直接用object类型的value和字符串"abc"比较,存在类型装箱导致的匹配失效问题,同时未处理value为null的场景。修改验证方法:protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { var lastName = value as string; // 若允许姓氏为空,可跳过null/空字符串的验证 if (!string.IsNullOrEmpty(lastName) && string.Equals(lastName, "abc", StringComparison.OrdinalIgnoreCase)) { return new ValidationResult("姓氏不能为abc"); } return ValidationResult.Success; }调整View中脚本加载顺序
原页面顶部重复加载了min和非min版本的脚本,且顺序完全错误(必须先加载jQuery,再加载Validate,最后加载Unobtrusive)。移除页面顶部所有脚本引用,保留@section Scripts中的内容即可(_ValidationScriptsPartial已包含正确顺序的必要脚本):@model Employee <div class="container"> <!-- 页面内容不变 --> </div> @section Scripts { <partial name="_ValidationScriptsPartial"></partial> <!-- 若需要额外验证方法,添加此行 --> <script src="~/lib/jquery-validation/dist/additional-methods.min.js"></script> }确认服务器端验证触发
提交表单时,断点调试[HttpPost] Create方法中的ModelState.IsValid,确认服务器端是否触发自定义验证。若客户端验证未生效,服务器端验证应该会正常执行,返回错误信息到页面。规范模型属性命名(可选)
将模型中的lastname改为LastName(遵循帕斯卡命名法),与ASP.NET Core的默认绑定规则保持一致,避免潜在的命名匹配问题。
内容的提问来源于stack exchange,提问作者user12589647
相关产品推荐
相关产品推荐

