Asp.net mvc 4 如何在MVC中比较模型属性与模型中多个字段的不相等性

Asp.net mvc 4 如何在MVC中比较模型属性与模型中多个字段的不相等性,asp.net-mvc-4,Asp.net Mvc 4,我是MVC技术的新手。今天我接到一个任务,要制作一个表单,用户可以在表单上输入多个电子邮件地址。我需要阻止用户在其他文本框中输入重复的电子邮件地址。我创建了一个用于比较的自定义验证器,称为“NonEqualValidation”,如下所示 [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)] public class NonEqualValidation : ValidationA

我是MVC技术的新手。今天我接到一个任务,要制作一个表单,用户可以在表单上输入多个电子邮件地址。我需要阻止用户在其他文本框中输入重复的电子邮件地址。我创建了一个用于比较的自定义验证器,称为“NonEqualValidation”,如下所示

 [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class NonEqualValidation : ValidationAttribute, IClientValidatable
{
    private const string DefaultErrorMessage = "Duplicate e-mail not allowed";
    public string OtherProperty { get; private set; }
    public string OtherPropertyName { get; private set; }

    public NonEqualValidation(string otherProperty, string otherPropertyName): base(DefaultErrorMessage)
    {
        OtherProperty = otherProperty;
        OtherPropertyName = otherPropertyName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            var otherProperty = validationContext.ObjectInstance.GetType().GetProperty(OtherProperty);

            var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);

            if (value.Equals(otherPropertyValue))
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
        }

        return ValidationResult.Success;

    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule()
        {
            ValidationType = "unlike",
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
        };

        rule.ValidationParameters.Add("otherproperty", OtherProperty);
        rule.ValidationParameters.Add("otherpropertyname", OtherPropertyName);

        yield return rule;
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format(ErrorMessageString, name, OtherPropertyName);
    }
}
但预期的结果仍然没有到来。如果我也输入了重复的值,它就不起作用了。有人能帮忙吗

我还添加了此jquery验证,以便在客户端进行验证,如下面的帖子所示。我无法将其粘贴为给定错误:


您可以使用远程验证。 模型

内部控制器

[HttpPost]
        public JsonResult doesEmailExist([Bind(Prefix = "Email.EmailName")]string EmailName)
        {
            var email = db.Emails.FirstOrDefault(a => a.EmailName == EmailName);
            return Json(email == null);
        }
希望这会有所帮助。

你很接近了

自定义属性实现: 创建一个从CompareAttribute派生的自定义属性,而不是从头开始实现新的自定义属性。然后重写IsValid方法

型号: 因为您有5个电子邮件属性,所以我会在每个电子邮件属性上放置一个CustomAttribute,以检查其他电子邮件属性

大概是这样的:

[EmailAddress(ErrorMessage = "Please enter valid e-mail address")]
[NonEqualValidation("MAILFRIEND5", "Duplicate e-mail not allowed")]
public string MAILFRIEND1 { get; set; }

[EmailAddress(ErrorMessage = "Please enter valid e-mail address")]
[NonEqualValidation("MAILFRIEND1", "Duplicate e-mail not allowed")]
public string MAILFRIEND2 { get; set; }

[EmailAddress(ErrorMessage = "Please enter valid e-mail address")]
[NonEqualValidation("MAILFRIEND2, "Duplicate e-mail not allowed")]
public string MAILFRIEND3 { get; set; }

[EmailAddress(ErrorMessage = "Please enter valid e-mail address")]
[NonEqualValidation("MAILFRIEND3, "Duplicate e-mail not allowed")]
public string MAILFRIEND4 { get; set; }

[EmailAddress(ErrorMessage = "Please enter valid e-mail address")]
[NonEqualValidation("MAILFRIEND4, "Duplicate e-mail not allowed")]
public string MAILFRIEND5 { get; set; }

下面是一个示例自定义属性

可以添加要作为逗号分隔字符串进行比较的属性

 public class CompareNotEqualAttribute : ValidationAttribute
{


    public List<string> CompareProperties { get; set; }
    public CompareNotEqualAttribute(string compareproperty)
    {
            CompareProperties = compareproperty.Split(',').ToList();
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        foreach(var compareProperty in CompareProperties)
        {
            var otherProperty = validationContext.ObjectType.GetProperty(compareProperty);
            if (otherProperty == null)
                return new ValidationResult(String.Format("Unknown property: {0}.", otherProperty));
            // get the other value
            var other = otherProperty.GetValue(validationContext.ObjectInstance, null);

            if (other.Equals(value))
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
            else
            {
                return null;
            }
        }
        return null;
    }
}
公共类CompareNodeQualatAttribute:ValidationAttribute
{
公共列表比较属性{get;set;}
公共CompareNodeQualatAttribute(字符串compareproperty)
{
CompareProperties=compareproperty.Split(',').ToList();
}
受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext)
{
foreach(CompareProperties中的var compareProperty)
{
var otherProperty=validationContext.ObjectType.GetProperty(compareProperty);
if(otherProperty==null)
返回新的ValidationResult(String.Format(“未知属性:{0}.”,otherProperty));
//获取另一个值
var other=otherProperty.GetValue(validationContext.ObjectInstance,null);
如果(其他等于(值))
{
返回新的ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
其他的
{
返回null;
}
}
返回null;
}
}

您可以实现以下功能:

 public class CompareNotEqualAttribute : ValidationAttribute
{

    public List<string> CompareProperties { get; set; }

    public CompareNotEqualAttribute(string compareproperty)
    {
            CompareProperties = compareproperty.Split(',').ToList();
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        foreach(var compareProperty in CompareProperties)
        {
            var otherProperty = validationContext.ObjectType.GetProperty(compareProperty);
            if (otherProperty == null)
                return new ValidationResult(String.Format("Unknown property: {0}.", otherProperty));
            // get the other value
            var other = otherProperty.GetValue(validationContext.ObjectInstance, null);

            if (other.Equals(value))
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
            else
            {
                return null;
            }
        }
        return null;
    }
}
公共类CompareNodeQualatAttribute:ValidationAttribute
{
公共列表比较属性{get;set;}
公共CompareNodeQualatAttribute(字符串compareproperty)
{
CompareProperties=compareproperty.Split(',').ToList();
}
受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext)
{
foreach(CompareProperties中的var compareProperty)
{
var otherProperty=validationContext.ObjectType.GetProperty(compareProperty);
if(otherProperty==null)
返回新的ValidationResult(String.Format(“未知属性:{0}.”,otherProperty));
//获取另一个值
var other=otherProperty.GetValue(validationContext.ObjectInstance,null);
如果(其他等于(值))
{
返回新的ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
其他的
{
返回null;
}
}
返回null;
}
}

在属性中,列出其他电子邮件地址,以逗号分隔。

服务器端或客户端(或两者)不工作?它是客户端。我正在使用jquery.validate.js和jquery.validate.unobtrusive.js使用数据注释使其在客户端工作。您是否向jquery验证器添加了方法?(例如,
$.validator.addMethod(…)
)。有一个
[NotEqualTo]
属性,它就可以做到这一点(经过尝试和测试!)。如果您想创建自己的,可能值得研究源代码。我已经创建了validation属性,正如您在上面所看到的,因为我使用的是使用数据注释的客户端验证,但是您还没有创建关联的jquery代码来处理
jquery validate unobtrusive.js
,因此您无法获得客户端验证。可能有助于您理解OP的情况这不起作用,因为它只检查数据库中的现有值,而不是用户在表单的其他文本框中输入的值(尚未保存)。它可能适合于使用
附加字段
传回其他tetbox的值,但如果只调用服务器来检查客户端上的内容,那就太过分了。当然,
[Remote]
不提供服务器端验证,但这里有一个问题。电子邮件1只能通过电子邮件5进行验证,而重复的电子邮件可以位于任何字段中,如MAILFRIEND2、MAILFRIEND3、MAILFRIEND4或MAILFRIEND5。对此有什么建议吗?有道理。我只使用了3个属性。在这种情况下,您可以构建一个自定义属性。见下文
 public class CompareNotEqualAttribute : ValidationAttribute
{


    public List<string> CompareProperties { get; set; }
    public CompareNotEqualAttribute(string compareproperty)
    {
            CompareProperties = compareproperty.Split(',').ToList();
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        foreach(var compareProperty in CompareProperties)
        {
            var otherProperty = validationContext.ObjectType.GetProperty(compareProperty);
            if (otherProperty == null)
                return new ValidationResult(String.Format("Unknown property: {0}.", otherProperty));
            // get the other value
            var other = otherProperty.GetValue(validationContext.ObjectInstance, null);

            if (other.Equals(value))
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
            else
            {
                return null;
            }
        }
        return null;
    }
}
 public class CompareNotEqualAttribute : ValidationAttribute
{

    public List<string> CompareProperties { get; set; }

    public CompareNotEqualAttribute(string compareproperty)
    {
            CompareProperties = compareproperty.Split(',').ToList();
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        foreach(var compareProperty in CompareProperties)
        {
            var otherProperty = validationContext.ObjectType.GetProperty(compareProperty);
            if (otherProperty == null)
                return new ValidationResult(String.Format("Unknown property: {0}.", otherProperty));
            // get the other value
            var other = otherProperty.GetValue(validationContext.ObjectInstance, null);

            if (other.Equals(value))
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
            else
            {
                return null;
            }
        }
        return null;
    }
}