简体   繁体   中英

How to create a custom Compare attribute with client-side validation?

The title says it all, but I'll add a bit of background here.

Until recently, I've been using MVC's already-written CompareAttribute to compare two values, in this case a password and its confirmation. It's worked well, except this attribute does not display the display name, set by the [Display(Name = "Name")] attribute of the property being compared.

Here are the two properties being compared:

[Required]
[Display(Name = "New Password")]
public string New { get; set; }

[Compare("New")]
[Display(Name = "Confirm Password")]
public string ConfirmPassword { get; set; }

The validation message reads as follows:

'Confirm Password' and 'New' do not match.

This works, but it's obviously not as good as it should be. The New should read as New Password , as specified by the Display attribute.

I have gotten this working, although not completely. The following implementation (for some reason) fixes the issue of not getting the specified name of the property, but I'm not sure why:

public class CompareWithDisplayNameAttribute : CompareAttribute
{
    public CompareWithDisplayNameAttribute(string otherProperty)
        : base(otherProperty)
    {
    }
}

Now, even though this works, client-side validation does not work. I've received an answer in another question that suggests using something like this

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CompareWithDisplayName), typeof(CompareAttributeAdapter))

in my Global.asax , however the CompareAttributeAdapter doesn't actually exist.

So here I am. I've got the Display attribute being used properly by my custom CompareWithDisplayName attribute, but client-side validation missing altogether.

How can I make client-side validation work with this solution in the cleanest way possible?

If you want your custom compare attribute to work with clientside validation you will need to implement IClientValidatable . This has GetValidationRules which is where you can do any custom validation you might wish.

Example

public class CompareWithDisplayNameAttribute : CompareAttribute, IClientValidatable
{
    public CompareWithDisplayNameAttribute(string otherProperty)
        : base(otherProperty)
    {
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
        ModelMetadata metadata, ControllerContext context)
    {
        // Custom validation goes here.
        yield return new ModelClientValidationRule();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM