Reputation: 3823
I have made a custom data annotation attribute which verifies whether an email already exists in my database like this:
public class ValidateEmail : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
using (var ctx = new myCtx())
{
if (value != null)
{
var valueAsString = value.ToString().ToLower();
IEnumerable<string> email = ctx.Users.Where(x => x.Email != null).Select(x => x.Email);
if (email.Contains(valueAsString))
{
var errorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(errorMessage);
}
}
return ValidationResult.Success;
}
}
}
And in my view model I set it like this:
[ValidateEmail(ErrorMessage = "Email exists")]
[Required(ErrorMessage = "Required")]
[RegularExpression(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$", ErrorMessage = "Invalid Email")]
public string Email { get; set; }
This works perfectly when the page reloads...But I would like now to change this so that I enable client side validation and message displaying without reloading the page itself...
How can I modify this validation attribute to make it compliable with jquery's unobstrusive validation in .NET MVC?
Based on @Sayan's link, I've implemented something like this:
public class ValidateEmail : ValidationAttribute, IClientValidatable
{
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationType = "emailvalidate";
yield return rule;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
using (var ctx = new myContext())
{
if (value != null)
{
var valueAsString = value.ToString().ToLower();
IEnumerable<string> email = ctx.Users.Where(x => x.Email != null).Select(x => x.Email);
if (email.Contains(valueAsString))
{
var errorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(errorMessage);
}
}
return ValidationResult.Success;
}
}
}
and client side:
$.validator.addMethod("emailvalidate", function (value, element) {
{
console.log("value: " + value + " " + element);
}});
$.validator.unobtrusive.adapters.add("emailvalidate", function (options) {
//adding rules for validator
options.rules["emailvalidate"] = true;
if (options.message) {
options.messages["emailvalidate"] = options.message;
}
});
But whatever I insert now in the email field as email like:
[email protected]
I get the error that email exists ?
Upvotes: 1
Views: 1662
Reputation: 4946
You can implement IClientValidatable
in your ValidateEmail
validation attribute to supply the data-val-xxx
attributes to the client side.
Then you can write the jQuery unobtrusive validator and adapter to validate the field value on client side using the data-val-xxx
rendered in HTML.
Make sure to return true
(truthy value) or false
(falsy value) from the jQuery validator based on whether the field value is valid or not respectively.
Lastly, include this custom jQuery validator script to your view.
You can find more details here. Though this blog post presents a slightly complicated scenario, but seeing how to use IClientValidatable
and how to write jQuery unobtrusive validator is enough.
Hope this is helpful.
Upvotes: 1