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

如何为继承IClientModelValidator的自定义NotEqualAttribute实现AddValidation方法

实现NotEqualAttribute的客户端验证支持

你已经搞定了服务器端的验证逻辑,现在只需要补全IClientModelValidator接口的AddValidation方法,就能让客户端的jQuery Unobtrusive验证和你的属性完美联动起来了!

完整的NotEqualAttribute代码

这里是加上客户端验证支持后的完整类代码:

using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; // ASP.NET Core 环境下引用这个命名空间

public class NotEqualAttribute : ValidationAttribute, IClientModelValidator
{
    public string OtherProperty { get; private set; }

    public NotEqualAttribute(string otherProperty)
    {
        OtherProperty = otherProperty;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var property = validationContext.ObjectType.GetProperty(OtherProperty);
        if (property == null)
        {
            return new ValidationResult(
                string.Format(
                    CultureInfo.CurrentCulture,
                    "{0} is unknown property",
                    OtherProperty
                )
            );
        }
        var otherValue = property.GetValue(validationContext.ObjectInstance, null);
        if (object.Equals(value, otherValue))
        {
            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        }
        return null;
    }

    // 实现IClientModelValidator接口的核心方法
    public void AddValidation(ClientModelValidationContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        // 标记该字段需要客户端验证
        MergeAttribute(context.Attributes, "data-val", "true");
        // 设置验证失败时的错误提示文本
        MergeAttribute(context.Attributes, "data-val-notequalto", FormatErrorMessage(context.ModelMetadata.GetDisplayName()));
        // 获取目标属性的HTML元素ID,传递给客户端验证方法
        var targetPropertyId = context.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(OtherProperty);
        MergeAttribute(context.Attributes, "data-val-notequalto-other", targetPropertyId);
    }

    // 辅助方法:避免重复添加相同属性
    private static void MergeAttribute(IDictionary<string, string> attributes, string key, string value)
    {
        if (!attributes.ContainsKey(key))
        {
            attributes.Add(key, value);
        }
    }
}

关键逻辑说明

  • AddValidation方法:负责把服务器端的验证规则转换成客户端能识别的HTML属性:
    • data-val="true":告诉Unobtrusive验证框架这个字段需要做客户端校验
    • data-val-notequalto:绑定验证失败时的错误消息,复用你已定义的错误消息格式化逻辑
    • data-val-notequalto-other:传递目标属性的HTML元素ID,对应你提供的jQuery适配器里的['other']参数
  • MergeAttribute辅助方法:确保同一个属性不会被重复添加,避免出现HTML属性冲突的问题

模型使用示例

在你的模型类里,就可以这样轻松使用这个属性:

public class UserRegisterModel
{
    [DisplayName("登录密码")]
    [Required(ErrorMessage = "请输入登录密码")]
    public string LoginPassword { get; set; }

    [DisplayName("安全密码")]
    [Required(ErrorMessage = "请输入安全密码")]
    [NotEqual("LoginPassword", ErrorMessage = "安全密码不能和登录密码相同")]
    public string SecurityPassword { get; set; }
}

注意事项

  • 确保页面已正确引入jquery.js、jquery.validate.js和jquery.validate.unobtrusive.js这三个脚本,引入顺序不能乱
  • 你提供的jQuery验证脚本无需修改,它会自动读取我们添加的HTML属性,完成客户端的不等值校验逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:58:11