asp.net-mvc - 我无法在 ASP.NET 应用程序上进行客户端验证
问题描述
我的问题
我尝试使用客户端验证创建自定义验证器。但是客户端验证端不起作用,我不明白为什么。
这是一个 .NET Core 3.1 应用程序。
我的代码
验证者:
public class ExcludeCharAttribute : ValidationAttribute, IClientValidatable
{
private readonly string _chars;
public ExcludeCharAttribute(string chars)
: base("{0} contains invalid character.")
{
_chars = chars;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
var valueAsString = value.ToString();
for (int i = 0; i < _chars.Length; i++)
{
if (valueAsString.Contains(_chars[i]))
{
var errorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(errorMessage);
}
}
}
return ValidationResult.Success;
}
//new method
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationParameters.Add("chars", _chars);
rule.ValidationType = "exclude";
yield return rule;
}
}
为了测试,我创建了这个测试 dto:
public class TestDto
{
[ExcludeChar("123456")]
public string Prop1 { get; set; }
[Required]
public string Prop2 { get; set; }
}
和那种形式:
<div class="row">
<div class="col-md-4">
<form asp-action="TestValidator">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Prop1" class="control-label"></label>
<input asp-for="Prop1" class="form-control" />
<span asp-validation-for="Prop1" class="text-danger"></span>
<label asp-for="Prop2" class="control-label"></label>
<input asp-for="Prop2" class="form-control" />
<span asp-validation-for="Prop2" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script src="~/js/validator.js"></script>
}
当然还有这个验证 js(validator.js):
$.validator.unobtrusive.adapters.addSingleVal("exclude", "chars");
$.validator.addMethod("exclude", function (value, element, exclude) {
if (value) {
for (var i = 0; i < exclude.length; i++) {
if (jQuery.inArray(exclude[i], value) != -1) {
return false;
}
}
}
return true;
});
发生什么事
测试时不运行客户端验证。检查代码时,我没有看到 Prop1 的任何 data-* 属性:
但是对于 Prop2 来说没关系。我认为这就是它不起作用的原因。
我测试的
测试了其他在线示例。
测试我加载了所有的JS:
测试脚本的 CDN 版本
我需要的
现在我不知道该怎么办。有人对缺少什么有想法吗?
谢谢你
解决方案
我复制了您的自定义验证代码并在我这边进行了测试,但效果很好,您能检查一下您的代码和我的代码之间的差异吗?我确定视图代码是相同的,并且在验证类中您可以检查使用包。
验证类:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace WebAppMvc.Models
{
public class ExcludeCharAttribute : ValidationAttribute, IClientValidatable
{
private readonly string _chars;
public ExcludeCharAttribute(string chars)
: base("{0} contains invalid character.")
{
_chars = chars;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
var valueAsString = value.ToString();
for (int i = 0; i < _chars.Length; i++)
{
if (valueAsString.Contains(_chars[i]))
{
var errorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(errorMessage);
}
}
}
return ValidationResult.Success;
}
//new method
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationParameters.Add("chars", _chars);
rule.ValidationType = "exclude";
yield return rule;
}
}
}
模型:
using System.ComponentModel.DataAnnotations;
namespace WebAppMvc.Models
{
public class UserModel
{
[Key]
[ExcludeChar("123456")]
public string id { get; set; }
public int userId { get; set; }
}
}
这是我的控制器方法:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create([Bind("id,userId")] UserModel user)
{
if (ModelState.IsValid)
{
return RedirectToAction("Index");
}
return View(user);
}
这是视图:
@model WebAppMvc.Models.UserModel
<h4>Test</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="id" class="control-label"></label>
<input asp-for="id" class="form-control" />
<span asp-validation-for="id" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="userId" class="control-label"></label>
<input asp-for="userId" class="form-control" />
<span asp-validation-for="userId" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
推荐阅读
- java - Reverse Integer leetcode:为什么只有在 INT_MAX 加上 7 或更大时才会发生溢出?
- java - 通过修改现有参数进行批处理
- powerbi - 如何使用工作日来衡量平均销售额?
- javascript - 使用 dd/mm/yyyy 进行年龄验证
- xml - xslt xml表格记录分页
- javascript - 我无法使用 onload 命令绑定 javascript 代码
- python - 转换包含实数的字符串列表
- swift - CoreML 模型在 coremltools 和 Xcode 之间产生不同的结果
- javascript - 你可以通过 Durandal activationData compose 绑定传递多个参数吗?
- java - 带有 JTable 的 Java GUI