I have an mvc application with this code:
public class Register
{
[RegularExpression(#"^(?=.*\d)(?=.*[a-zA-Z]).{7,14}$", ErrorMessage = "Password is not in proper format")]
public string Password{ get; set; }
}
What it does is validate the password to contain atleast 7-14 characters, atleast 1 number and 1 upper case letter.
Another requirement is it should not be the same as the email address.
How can I do that? It seems [Compare(Email)] would not be possible on this scenario?
Thanks in advance!
Using MVC Foolproof Validation you can write
[NotEqualTo("EmailAddress", ErrorMessage="Passwords must be different that EmailAddress")]
public string Password{ get; set; }
http://foolproof.codeplex.com/
The easiest way: create your own attribute which inherits CompareAttribute, and override IsValid method. The full code will be like following:
public class NotEqualTo: CompareAttribute
{
public NotEqualTo(string otherProperty) : base(otherProperty)
{
}
protected override System.ComponentModel.DataAnnotations.ValidationResult IsValid(object value,
System.ComponentModel.
DataAnnotations.
ValidationContext
validationContext)
{
PropertyInfo property = validationContext.ObjectType.GetProperty(this.OtherProperty);
if (property == (PropertyInfo) null)
{
return
new ValidationResult(string.Format((IFormatProvider) CultureInfo.CurrentCulture,
"Property {0} does not exist", new object[1]
{
(object) this.OtherProperty
}));
}
else
{
object objB = property.GetValue(validationContext.ObjectInstance, (object[]) null);
if (object.Equals(value, objB))
return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
else
return (ValidationResult) null;
}
}
}
Related
using asp.net mvc 5
I have create a Custom conditional validation which is working perfectly when it is getting posted to controller but not working in client side -
and I am showing the code like below
if (!ModelState.IsValid)
{
return View("Index", model);
}
1 .I could not find any way in asp.net mvc which will work without the Jquery code - if you can suggest or show any other way without writing client side code manually that is preferable
If its not possible without writing client side code by myself , then how can i send two three error message from server , make it work in the client side
View Model
[ValidateTargetId]
public string TargetId{ get; set; }
[Required]
public string DependentProperty{ get; set; }
public SelectList DependentPropertyDropDownList { get; set; }
Custom Validator class
public class ValidateTargetIdAttribute : ValidationAttribute , IClientValidatable
{
protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
{
object instance = validationContext.ObjectInstance;
Type type = instance.GetType();
PropertyInfo property = type.GetProperty("DependentProperty");
object propertyValue = property.GetValue(instance);
value = value == null ? "" : value.ToString();
if (propertyValue == null)
{
return null;
}
else
{
switch (propertyValue.ToString().ToUpper())
{
case "Case1":
if (!string.IsNullOrEmpty(value.ToString()))
{
return new
ValidationResult("target id should be blank");
}
break;
case "Case2":
if (value.ToString().Trim().Length != 15)
{
return new ValidationResult("Target Id should have length 15 ");
}
break;
case "Case3":
if (value.ToString().Trim().Length != 20)
{
return new ValidationResult("Target Id Should have length 20");
}
break;
}
return null;
}
}
//for client side
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule mvr = new ModelClientValidationRule();
mvr.ErrorMessage = "target id should be blank ";
mvr.ValidationType = "validtarget";
return new[] { mvr };
}
}
Jquery
$(function() {
jQuery.validator.addMethod('validtarget', function (value, element, params) {
// how to create this logic
}, '');
jQuery.validator.unobtrusive.adapters.add('validtarget', function (options) {
options.rules['validtarget] = {};
options.messages['validtarget'] = options.message;
});
}(jQuery));
I am using Enterprise Library 6 Validation in WCF. I have made a Custom Validator. When I use it I specify a MessageTemplate. When error Occurs, instead of showing MessageTemplate it shows the message given in DoValidate of the custom validator.
Custom Validator
public sealed class EmailValidatorAttribute : ValidatorAttribute
{
protected override Validator DoCreateValidator(Type targetType)
{
return new EmailValidator();
}
}
public sealed class EmailValidator : Validator
{
public EmailValidator()
: base("Email Validation", "String")
{
}
protected override string DefaultMessageTemplate
{
get { return "Email Validation"; }
}
// This method does the actual validation
public override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults validationResults)
{
Regex emailRegex = new Regex(IConnect.DataContract.WCFServiceResources.EmailRegex);
Match match = emailRegex.Match((string)objectToValidate);
if (!match.Success)
{
LogValidationResult(validationResults, "Invalid Email Address.", currentTarget, key);
}
}
}
WCF
[OperationContract]
[FaultContract(typeof(ValidationFault))]
string EmailAddressCheck([EmailValidator(MessageTemplate = "Enter a Valid Email ID.")]string email);
Currently it is showing "Invalid Email Address." defined in
DoValidate of Custom Validator Code
But
I want to show "Enter a Valid Email ID." defined in MessageTemplate in WCF Code
How to do so?
Finally I found answer to my question.
public override void DoValidate(
object objectToValidate,
object currentTarget,
string key,
ValidationResults validationResults)
{
Regex emailRegex = new Regex(IConnect.DataContract.WCFServiceResources.EmailRegex);
Match match = emailRegex.Match((string)objectToValidate);
if (!match.Success)
{
LogValidationResult(
validationResults,
// The next line does the trick
string.Format(this.MessageTemplate, new object[] { objectToValidate }),
currentTarget,
key);
}
}
The part in LogValidationResult that does the trick is:
string.Format(this.MessageTemplate, new object[] { objectToValidate })
Does anyone know of a CompareAttribute data annotation for WPF, or a way of achieving the same result in WPF?
For those that don't immediately know, CompareAttribute is a property data annotation for validating in WPF, it takes a string for a second property and returns true if the decorated property and the passed property match.
Basically I need to validate a password change form, to ensure the "retyped password" matches the new password, and do this with data annotations so that i can use the xaml validation template.
You can create your own custom validation logic by creating your own CustomValidationAttribute descrided here.
Try Custom Validator like this
public class EqualsValidationAttribute : ValidationAttribute
{
string propertyToCompare;
public EqualsValidationAttribute(string propertyToCompare)
{
this.propertyToCompare = propertyToCompare;
}
public EqualsValidationAttribute(string propertyToCompare,string errorMessage):this(propertyToCompare)
{
this.ErrorMessage = propertyToCompare;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var propInfo=validationContext.ObjectInstance.GetType().GetProperty(propertyToCompare);
if (propInfo != null)
{
var propValue=propInfo.GetValue(validationContext.ObjectInstance);
if(value!=null && propValue!=null && !string.IsNullOrEmpty(value.ToString()) && !string.IsNullOrEmpty(propValue.ToString()) //if either one is empty dont Validate
&& (value.ToString() != propValue.ToString()))
return new ValidationResult(ErrorMessage);
}
else
throw new NullReferenceException("propertyToCompare must be the name of property to compare");
return ValidationResult.Success;
}
}
and use it in Entity like this
[Required(ErrorMessage="Password Required")]
public string Password {
get { return password; }
set { password = value; RaisePropertyChanged("Password"); }
}
[EqualsValidationAttribute("Password", ErrorMessage = "Confirm password must be same as password")]
public string ConfirmPassword {
get { return confirmedpassword; }
set { confirmedpassword = value; RaisePropertyChanged("ConfirmPassword"); }
}
}
i am using asp.net MVC 3 , in my module there are two types of payment modes 1. Wire transfer and 2. PayPal . Now depending on this type 1 and 2 the properties are to be kept Required or other data annotations ! how to do this ?
for eg :
There is a Radio button for payment type ,
If type 1- i.e Wire Transfer is selected then these fields should be validated - First name , last name , email,beneficiary name , bank name , bank no , ifsc code etc
if it is type 2- i.e PayPal then these fields are required - PayPal email .
This could be done by manual validation but is there some way to do it the right way with DataAnnotations?
Simon Ince's blog post seems to be outdated.
There is no need to use DataAnnotationsModelValidator or do a DataAnnotationsModelValidator registration.
You can use the following code:
[AttributeUsage(AttributeTargets.Property, AllowMultiple=false)]
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable {
private const string _defaultErrorMessage = "'{0}' is required when {1} equals {2}.";
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public RequiredIfAttribute(string dependentProperty, object targetValue):base(_defaultErrorMessage) {
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}
public override string FormatErrorMessage(string name) {
return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, DependentProperty, TargetValue);
}
protected override ValidationResult IsValid(object value, ValidationContext context) {
if (context.ObjectInstance != null) {
Type type = context.ObjectInstance.GetType();
PropertyInfo info = type.GetProperty(DependentProperty);
object dependentValue;
if (info != null) {
dependentValue = info.GetValue(context.ObjectInstance, null);
if (object.Equals(dependentValue, TargetValue)) {
if (string.IsNullOrWhiteSpace(Convert.ToString(value))) {
return new ValidationResult(ErrorMessage);
}
}
}
}
return ValidationResult.Success;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
ModelClientValidationRule rule = new ModelClientValidationRule();
rule.ErrorMessage = this.FormatErrorMessage(metadata.PropertyName);
rule.ValidationType = "requiredif";
rule.ValidationParameters.Add("depedentproperty", DependentProperty);
rule.ValidationParameters.Add("targetvalue", TargetValue);
yield return rule;
}
}
and the javascript side: if you are using jquery:
$.validator.unobtrusive.adapters.add('requiredif', ['depedentproperty', 'targetvalue'], function (options) {
options.rules["required"] = function (element) {
return $('#' + options.params.depedentproperty).val() == options.params.targetvalue
};
if (options.message) {
options.messages["required"] = options.message;
}
$('#' + options.params.depedentproperty).blur(function () {
$('#' + options.element.name).valid();
});
});
I've updated my example to use MVC 3, so that one is more up to date.
http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx
You could write a custom validator attribute and decorate your model with it:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class CustomValidationAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
var model = value as MyViewModel;
if (model == null)
{
return false;
}
if (model.WireTransfer == 1)
{
return !string.IsNullOrEmpty(model.FirstName) &&
!string.IsNullOrEmpty(model.LastName);
}
else if (model.WireTransfer == 2)
{
return !string.IsNullOrEmpty(model.PaypalEmail);
}
return false;
}
}
and then in your main Model:
[CustomValidation]
public class MyViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
...
}
I have used the approach from Simon Ince's blog post and it works well. Basically he creates a RequiredIf data attribute where you can specify the other property and value that must be true in order to make the current field required.
I have two fields in my form
AccountNumber
ReverseAccountNumber
Can i use data annotations to validate that the value of "ReverseAccountNumber" textbox is equal to the reversed value of "AccountNumber".
i.e.
AccountNumber = 12345
ReverseAccountNumber = 54321
i expect the validation to occur on the lostFocus event of the ReverseAccountNumber textbox.
I think i can do this using IDataErrorInfo, However I believe this would require a POST first before validation occurs, and i consider it a last resort.
Simply add a validation attribute to the class (not the properties) and evaluate the class object to compare the two properties. As for the client side, ASP.NET MVC 3 should be able to generate proper client-side validation for this (although I have not tried it myself since Iam still using xVal).
CustomAttribute
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public sealed class ReversStringMatchAttribute : ValidationAttribute
{
public string Property { get; set; }
public ReversStringMatchAttribute()
{ }
public override bool IsValid(object value)
{
return true;
}
}
CustomValidator
public class ReversStringValidator : DataAnnotationsModelValidator<ReversStringMatchAttribute>
{
string property;
public ReversStringValidator(ModelMetadata metadata, ControllerContext context, ReversStringMatchAttribute attribute)
: base(metadata, context, attribute)
{
property = attribute.Property;
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
var rule = new ModelClientValidationRule
{
ErrorMessage = Attribute.ErrorMessage,
ValidationType = "reversStringValidator"
};
rule.ValidationParameters.Add("propertyname", property);
return new[] { rule };
}
}
Java Script
Sys.Mvc.ValidatorRegistry.validators["reversStringValidator"] = function (rule) {
//initialization
//return validator function
return function (value, context) {
var field = $get(rule.ValidationParameters['propertyname']);
if (field == null)
return "Property name is invalid!";
var s1 = field.value;
if (s1) {
if (value) {
var reverse = value.split("").reverse().join("");
if (s1 != reverse.toString()) {
return rule.ErrorMessage;
}
} else {
return rule.ErrorMessage;
}
}
return true;
}
};
then use it on your property
public class AccountViewModel
{
[Required(ErrorMessage="Account Number is Required")]
public string AccountNumber { get; set; }
[ReversStringMatch(ErrorMessage = "The value doesn't match the Account Number", Property="AccountNumber")]
public string ReverseAccountNumber { get; set; }
}
i have some doubts on the $get validation method in javascript but it works, for now.