Get value of a property that was passed in as a string - c#

I am trying to create a custom validation that says "if the otherValue is true, then this value must be greater than 0. I am able to get the value in, but the way I currently have the otherValue set up, I only have the name of the property, not the value. Probably because it passed in as a string. This attribute is going to be on 5 or 6 different properties and each time, it will be calling a different otherValue. Looking for help on how to get the actual value (it is a bool) of otherValue.
Here is my current code:
public class MustBeGreaterIfTrueAttribute : ValidationAttribute, IClientValidatable
{
// get the radio button value
public string OtherValue { get; set; }
public override bool IsValid(object value)
{
// Here is the actual custom rule
if (value.ToString() == "0")
{
if (OtherValue.ToString() == "true")
{
return false;
}
}
// If all is ok, return successful.
return true;
}
======================EDIT=========================
Here is where I am at now, and it works! Now I need a refernce on how to make it so I can put in a different errorMessage when adding the attribute in the model:
public class MustBeGreaterIfTrueAttribute : ValidationAttribute, IClientValidatable
{
// get the radio button value
public string OtherProperty { get; set; }
protected override ValidationResult IsValid(object value, ValidationContext context)
{
var otherPropertyInfo = context.ObjectInstance.GetType();
var otherValue = otherPropertyInfo.GetProperty(OtherProperty).GetValue(context.ObjectInstance, null);
// Here is the actual custom rule
if (value.ToString() == "0")
{
if (otherValue.ToString().Equals("True", StringComparison.InvariantCultureIgnoreCase))
{
return new ValidationResult("Ensure all 'Yes' answers have additional data entered.");
}
}
// If all is ok, return successful.
return ValidationResult.Success;
}
// Add the client side unobtrusive 'data-val' attributes
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ValidationType = "requiredifyes";
rule.ErrorMessage = this.ErrorMessage;
rule.ValidationParameters.Add("othervalue", this.OtherProperty);
yield return rule;
}
}
So I should be able to do this:
[MustBeGreaterIfTrue(OtherProperty="EverHadRestrainingOrder", ErrorMessage="Enter more info on your RO.")]
public int? ROCounter { get; set; }

The ValidationAttribute has a pair of IsValid methods and for your scenario you have to use other guy.
public class MustBeGreaterIfTrueAttribute : ValidationAttribute
{
// name of the OtherProperty. You have to specify this when you apply this attribute
public string OtherPropertyName { get; set; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var otherProperty = validationContext.ObjectType.GetProperty(OtherPropertyName);
if (otherProperty == null)
return new ValidationResult(String.Format("Unknown property: {0}.", OtherPropertyName));
var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);
if (value.ToString() == "0")
{
if (otherPropertyValue != null && otherPropertyValue.ToString() == "true")
{
return null;
}
}
return new ValidationResult("write something here");
}
}
Example Usage:
public class SomeModel
{
[MustBeGreaterIf(OtherPropertyName="Prop2")]
public string Prop1 {get;set;}
public string Prop2 {get;set;}
}
Ref: http://www.concurrentdevelopment.co.uk/blog/index.php/2011/01/custom-validationattribute-for-comparing-properties/

I'm having a little bit of trouble understanding what you want to do, but,
If you want to get the boolean representation of OtherValue, you could do
bool.Parse(this.OtherValue);
also, for string comparison, it sometimes helps to take case and whitespace out of the picture
if (this.OtherValue.ToString().ToLower().Trim() == "true")

validationContext has ObjectInstance which is an instance of SomeModel class so you can use:
(validationContext.ObjectInstance as SomeModel).Prop1/Prop2

Related

Custom Validation attribute not working on client side

I have create following custom requiredif attribute and added client side script also validation is working on server side. tag is updated with data-val attributes but client side validation is not triggering. Couldn't figure aout what's I am missing here
public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator//ValidationAttribute
{
private string dependentProperty;
private object targetValue;
public RequiredIfAttribute(string _DependentProperty, object _TargetValue)
{
this.dependentProperty=_DependentProperty ;
this.targetValue=_TargetValue ;
}
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val-requiredif-dependentproperty", dependentProperty);
MergeAttribute(context.Attributes, "data-val-requiredif-targetvalue","true");
MergeAttribute(context.Attributes, "data-val-requiredif",GetErrorMessage(context));
}
bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
private string GetErrorMessage(ClientModelValidationContext context)
{
return string.Format("{0} is not a valid",
context.ModelMetadata.GetDisplayName());
}
protected override ValidationResult IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext)
{
var propertyTestedInfo = validationContext.ObjectType.GetProperty(this.dependentProperty);
if (propertyTestedInfo == null)
{
return new ValidationResult(string.Format("{0} needs to be exist in this object.", this.dependentProperty));
}
var dependendValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);
if (dependendValue == null)
{
return new ValidationResult(string.Format("{0} needs to be populated.", this.dependentProperty));
}
if (!dependendValue.Equals(this.targetValue))
{
var fieldValue = validationContext.ObjectType.GetProperty(validationContext.MemberName).GetValue(validationContext.ObjectInstance, null);
if (fieldValue != null)
{
return ValidationResult.Success;
}
else
{
return new ValidationResult(string.Format("{0} cannot be null", validationContext.MemberName));
}
}
else
{
// Must be ignored
return ValidationResult.Success;
}
}
}
Javascript Code
<script>
$.validator.addMethod('requiredif',
function (value, element, parameters) {
var id = '#' + parameters['dependentproperty'];
// get the target value (as a string,
// as that's what actual value will be)
var targetvalue = parameters['targetvalue'];
targetvalue =
(targetvalue == null ? '' : targetvalue).toString();
// get the actual value of the target control
// note - this probably needs to cater for more
// control types, e.g. radios
var control = $(id);
var controltype = control.attr('type');
var actualvalue =
controltype === 'checkbox' ?
control.attr('checked').toString() :
control.val();
// if the condition is true, reuse the existing
// required field validator functionality
if (targetvalue === actualvalue)
return $.validator.methods.required.call(
this, value, element, parameters);
return true;
}
);
$.validator.unobtrusive.adapters.add(
'requiredif',
['dependentproperty', 'targetvalue'],
function (options) {
options.rules['requiredif'] = {
dependentproperty: options.params['dependentproperty'],
targetvalue: options.params['targetvalue']
};
options.messages['requiredif'] = options.message;
});
</script>
Generated Tag and class property are as follows
<select data-val-requiredif="ToPositionID is not a valid" data-val-requiredif-dependentproperty="chkToPosReq" data-val-requiredif-targetvalue="true" id="ToPositionID" name="ToPositionID">
Class
public class VMWorkflow
{
[RequiredIf("chkToPosReq", "1")]
public int? ToPositionID { get; set; }
}

ASP.NET MVC custom multiple fields validation

I'm developing an ASP.NET MVC 5.2.3 custom data annotation for validation in Visual Studio 2015. It needs to take any number of fields and ensure that if one has a value, they all must have a value; if they're all null/blank, it should be okay.
A few examples have helped:
ASP.NET MVC implement custom validator use IClientValidatable
MVC Form Validation on Multiple Fields
http://www.macaalay.com/2014/02/24/unobtrusive-client-and-server-side-age-validation-in-mvc-using-custom-data-annotations/
However, I'm not sure how to do the client-side validation where you have an unknown number of fields being validated.
How do you pass that to the client using the implementation of the GetClientValidationRules() method of the IClientValidatable interface?
Also, how do I apply this new data annotation to the properties on my view model? Would it look like this?
[MultipleRequired("AppNumber", "UserId", /* more fields */), ErrorMessage = "Something..."]
[DisplayName("App #")]
public int AppNumber { get; set; }
[DisplayName("User ID")]
public int UserId { get; set; }
Here's as far as I could get with the MultipleRequiredAttribute custom data annotation class:
public class MultipleRequiredAttribute : ValidationAttribute, IClientValidatable
{
private readonly string[] _fields;
public MultipleRequiredAttribute(params string[] fields)
{
_fields = fields;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// If any field has value, then all must have value
var anyHasValue = _fields.Any(f => !string.IsNullOrEmpty(f));
if (!anyHasValue) return null;
foreach (var field in _fields)
{
var property = validationContext.ObjectType.GetProperty(field);
if (property == null)
return new ValidationResult($"Property '{field}' is undefined.");
var fieldValue = property.GetValue(validationContext.ObjectInstance, null);
if (string.IsNullOrEmpty(fieldValue?.ToString()))
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return null;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = ErrorMessage,
ValidationType = "multiplerequired"
};
}
}
Thank you.
In order to get client side validation, you need to pass the values of the 'other properties' in the ModelClientValidationRule by using the .Add() method of the rules ValidationParameters property, and then write the client side scripts to add the rules to the $.validator.
But first there are a few other issues to address with your attribute. First you should execute your foreach loop only if the value of the property you applied the attribute is null. Second, returning a ValidationResult if one of the 'other properties' does not exist is confusing and meaningless to a user and you should just ignore it.
The attribute code should be (note I changed the name of the attribute)
public class RequiredIfAnyAttribute : ValidationAttribute, IClientValidatable
{
private readonly string[] _otherProperties;
private const string _DefaultErrorMessage = "The {0} field is required";
public RequiredIfAnyAttribute(params string[] otherProperties)
{
if (otherProperties.Length == 0) // would not make sense
{
throw new ArgumentException("At least one other property name must be provided");
}
_otherProperties = otherProperties;
ErrorMessage = _DefaultErrorMessage;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null) // no point checking if it has a value
{
foreach (string property in _otherProperties)
{
var propertyName = validationContext.ObjectType.GetProperty(property);
if (propertyName == null)
{
continue;
}
var propertyValue = propertyName.GetValue(validationContext.ObjectInstance, null);
if (propertyValue != null)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
}
return ValidationResult.Success;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ValidationType = "requiredifany",
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
};
/ pass a comma separated list of the other propeties
rule.ValidationParameters.Add("otherproperties", string.Join(",", _otherProperties));
yield return rule;
}
}
The scripts will then be
sandtrapValidation = {
getDependentElement: function (validationElement, dependentProperty) {
var dependentElement = $('#' + dependentProperty);
if (dependentElement.length === 1) {
return dependentElement;
}
var name = validationElement.name;
var index = name.lastIndexOf(".") + 1;
var id = (name.substr(0, index) + dependentProperty).replace(/[\.\[\]]/g, "_");
dependentElement = $('#' + id);
if (dependentElement.length === 1) {
return dependentElement;
}
// Try using the name attribute
name = (name.substr(0, index) + dependentProperty);
dependentElement = $('[name="' + name + '"]');
if (dependentElement.length > 0) {
return dependentElement.first();
}
return null;
}
}
$.validator.unobtrusive.adapters.add("requiredifany", ["otherproperties"], function (options) {
var element = options.element;
var otherNames = options.params.otherproperties.split(',');
var otherProperties = [];
$.each(otherNames, function (index, item) {
otherProperties.push(sandtrapValidation.getDependentElement(element, item))
});
options.rules['requiredifany'] = {
otherproperties: otherProperties
};
options.messages['requiredifany'] = options.message;
});
$.validator.addMethod("requiredifany", function (value, element, params) {
if ($(element).val() != '') {
// The element has a value so its OK
return true;
}
var isValid = true;
$.each(params.otherproperties, function (index, item) {
if ($(this).val() != '') {
isValid = false;
}
});
return isValid;
});

How to get property name by one of it's attributes' value using reflection or how to get property info of data property which is currently validating?

I want to write custom validation attribute and add additional member names which have validation errors to validation result. The thing is I want to generate member name dynamically based on property name and invalid match property index or key (I want to validate IEnumerables or IDictionaries) like Names[0], Names[1], Names[key] etc. For example:
Model:
public class ModelClass
{
[ItemMaxLength(10)]
[Display(ResourceType = typeof(CategoriesRename), Name = "CategoryNamesFieldName")]
public IDictionary<string, string> Names { get; set; }
}
Attribute:
public class ItemMaxLengthAttribute : ValidationAttribute
{
private readonly int _maxLength = int.MaxValue;
public ItemMaxLengthAttribute(int maxLength)
{
_maxLength = maxLength;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
...
// I can get instance and it's type from validation context
var instance = validationContext.ObjectInstance; // which is instance of ModelClass
var instanceType = validationContext.ObjectType; //which is typeof(ModelClass)
var dispayName = validationContext.DisplayName; //which is value of Display attribute
...
}
}
So the main idea is (I don't like it ether) get current property been validated by it's DysplayName attribute value (dispayName). I'm kind'a stuck here for a while. Maybe is there some other way to get property info of the property which is validating?
P.S. I've already tried MemberName property, as Alexandre Rondeau suggested, but the problem is that validationContext.MemberName = null so it can't be used. Also MSDN says that this property represents an entity member name, not the name of a corresponding data field and I need the name of a corresponding data field.
Using that code, both test passes, so the MemberName isn't null.
[TestClass]
public class RefectionInValidationTest
{
[TestMethod]
public void GivenAModelWithItemMaxAttributeOnFieldName_WhenValidating_ThenModelClassIsValid()
{
//Arange
var validModelClass = new ModelClass();
var validations = new Collection<ValidationResult>();
//Act
var isValid = Validator.TryValidateObject(validModelClass, new ValidationContext(validModelClass, null, null), validations, true);
//Assert
Assert.IsTrue(isValid);
}
[TestMethod]
public void GivenAModelWithItemMaxAttributeOnFieldNotName_WhenValidating_ThenModelClassIsInvalid()
{
//Arange
var invalidaModelClass = new InvalidModelClass();
var validations = new Collection<ValidationResult>();
//Act
var isValid = Validator.TryValidateObject(invalidaModelClass, new ValidationContext(invalidaModelClass, null, null), validations, true);
//Assert
Assert.IsFalse(isValid);
}
}
public class ModelClass
{
[ItemMaxLength(10)]
public IDictionary<string, string> Names { get; set; }
}
public class InvalidModelClass
{
[ItemMaxLength(10)]
public IDictionary<string, string> NotNames { get; set; }
}
public class ItemMaxLengthAttribute : ValidationAttribute
{
private readonly int _maxLength = int.MaxValue;
public ItemMaxLengthAttribute(int maxLength)
{
_maxLength = maxLength;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var propretyInfo = validationContext.ObjectType.GetProperty(validationContext.MemberName);
if (propretyInfo.Name == "Names")
return ValidationResult.Success;
return new ValidationResult("The property isn't 'Names'");
}
}
You have to use validationContext.MemberName property.
Example:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var userManager = validationContext.GetService<UserManager<ApplicationUser>>();
var findingTask = userManager.FindByEmailAsync((string)value);
findingTask.Wait();
var user = findingTask.Result;
return user == null
? ValidationResult.Success
: new ValidationResult("This email already in use", new string[] { validationContext.MemberName });
}

How to pass parameters into a ValidationAttribute?

I have a custom ValidationAttribute, it checks if another user exists already.
To so it needs access to my data access layer, an instance injected into my controller by Unity
How can I pass this (or anything for that matter) as a parameter into my custom validator?
Is this possible? i.e where I'm creating Dal, that should be a paramter
public class EmailIsUnique : ValidationAttribute
{
private string _errorMessage = "An account with this {0} already exists";
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
DataAccessHelper Dal = new DataAccessHelper(SharedResolver.AppSettingsHelper().DbConnectionString); //todo, this is way too slow
bool isValid = true;
if(value == null) {
isValid = false;
_errorMessage = "{0} Cannot be empty";
} else {
string email = value.ToString();
if (Dal.User.FindByEmail(email) != null)
{
isValid = false;
}
}
if (isValid)
return ValidationResult.Success;
else
return new ValidationResult(String.Format(_errorMessage, validationContext.DisplayName));
}
}
I'm not too sure you'll be able to pass runtime parameters into your attribute.
You could use DependencyResolver.Current.GetService<DataAccessHelper>() to resolve your dal (given that you've registered DataAccessHelper)
You're probably more likely to have registered DataAccessHelper as IDataAccessHelper or something? in which case you'd call GetService<IDataAccessHelper>
public class EmailIsUnique : ValidationAttribute
{
private string _errorMessage = "An account with this {0} already exists";
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
IDataAccessHelper Dal = DependencyResolver.Current.GetService<IDataAccessHelper>(); // too slow
bool isValid = true;
if(value == null) {
isValid = false;
_errorMessage = "{0} Cannot be empty";
} else {
string email = value.ToString();
if (Dal.User.FindByEmail(email) != null)
{
isValid = false;
}
}
if (isValid)
return ValidationResult.Success;
else
return new ValidationResult(String.Format(_errorMessage, validationContext.DisplayName));
}
}
or
public class EmailIsUnique : ValidationAttribute
{
[Dependency]
public IDataAccessHelper DataAccess {get;set;}
private string _errorMessage = "An account with this {0} already exists";
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
bool isValid = true;
if(value == null)
{
isValid = false;
_errorMessage = "{0} Cannot be empty";
}
else
{
string email = value.ToString();
if (DataAccess.User.FindByEmail(email) != null)
{
isValid = false;
}
}
if (isValid)
return ValidationResult.Success;
else
return new ValidationResult(String.Format(_errorMessage, validationContext.DisplayName));
}
}
You are probably looking for Property Injection. Have a look at this post.
First solution is to create your custom filter provider that supports dependency injection.
Second solution is to use Service Locator pattern and get instance of you service in attribute constructor.
yes.you can pass parameter which use in the Model class as below:
[EmailIsUnique()]
public string Email {get; set;}
so this will automatically pass Email as a parameter and check the value.

Writing a CompareTo DataAnnotation Attribute

I have a situation where I want to compare to fields (example, ensuring the start time is before the end time). I'm using the System.ComponentModel.DataAnnotations attributes for my validation.
My first thought was something like this:
public enum CompareToOperation
{
EqualTo,
LessThan,
GreaterThan
}
public class CompareToAttribute : ValidationAttribute
{
CompareToOperation _Operation;
IComparable _Comparision;
public CompareToAttribute(CompareToOperation operation, Func<IComparable> comparison)
{
_Operation = operation;
_Comparision = comparison();
}
public override bool IsValid(object value)
{
if (!(value is IComparable))
return false;
switch (_Operation)
{
case CompareToOperation.EqualTo: return _Comparision.Equals(value);
case CompareToOperation.GreaterThan: return _Comparision.CompareTo(value) == 1;
case CompareToOperation.LessThan: return _Comparision.CompareTo(value) == -1;
}
return false;
}
}
public class SimpleClass
{
public DateTime Start {get;set;}
[CompareTo(CompareToOperation.GreaterThan, () => this.Start)] // error here
public DateTime End {get;set;}
}
This doesn't work however, there's a compiler error where the attribute is marked:
Expression cannot contain anonymous methods or lambda expressions
Does anyone have a solution for this? Or a different approach for validating one field compared to the value of another?
Check The AccountMOdel in the default project of MVC2, There is an attribute PropertiesMustMatchAttribute applied to the ChangePasswordModel to validate that the NewPassword and ConfirmPassword Match
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class PropertiesMustMatchAttribute : ValidationAttribute
{
private const string _defaultErrorMessage = "'{0}' and '{1}' do not match.";
private readonly object _typeId = new object();
public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty)
: base(_defaultErrorMessage)
{
OriginalProperty = originalProperty;
ConfirmProperty = confirmProperty;
}
public string ConfirmProperty
{
get;
private set;
}
public string OriginalProperty
{
get;
private set;
}
public override object TypeId
{
get
{
return _typeId;
}
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
OriginalProperty, ConfirmProperty);
}
public override bool IsValid(object value)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value);
object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value);
return Object.Equals(originalValue, confirmValue);
}
}
A very ugly way that's not nearly as flexible is to put it on the class and use reflection. I haven't tested this, so I'm not actually sure it works, but it does compile :)
public enum CompareToOperation
{
EqualTo,
LessThan,
GreaterThan
}
public class CompareToAttribute : ValidationAttribute
{
CompareToOperation _Operation;
string _ComparisionPropertyName1;
string _ComparisionPropertyName2;
public CompareToAttribute(CompareToOperation operation, string comparisonPropertyName1, string comparisonPropertyName2)
{
_Operation = operation;
_ComparisionPropertyName1 = comparisonPropertyName1;
_ComparisionPropertyName2 = comparisonPropertyName2;
}
private static IComparable GetComparablePropertyValue(object obj, string propertyName)
{
if (obj == null) return null;
var type = obj.GetType();
var propertyInfo = type.GetProperty(propertyName);
if (propertyInfo == null) return null;
return propertyInfo.GetValue(obj, null) as IComparable;
}
public override bool IsValid(object value)
{
var comp1 = GetComparablePropertyValue(value, _ComparisionPropertyName1);
var comp2 = GetComparablePropertyValue(value, _ComparisionPropertyName2);
if (comp1 == null && comp2 == null)
return true;
if (comp1 == null || comp2 == null)
return false;
var result = comp1.CompareTo(comp2);
switch (_Operation)
{
case CompareToOperation.LessThan: return result == -1;
case CompareToOperation.EqualTo: return result == 0;
case CompareToOperation.GreaterThan: return result == 1;
default: return false;
}
}
}
[CompareTo(CompareToOperation.LessThan, "Start", "End")]
public class SimpleClass
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
From the look of it, this cannot be done.
ValidationAttribute is applied on a property and as such is restricted to that property only.
I assume the question is not an abstract one and you do have a real issue that requires the presence of such a validator. Probably it's the repeat password textbox? :-)
In any case, to work around the problem you have you need to rely on the context you work in. ASP.NET Web Forms did it with the ControlToCompare and since everything is a control and we have naming containers in place it's fairly easy to figure things out based on a simple string.
In ASP.NET MVC you can in theory do the same thing, BUT! Client side will be fairly easy and natural - just use the #PropertyName and do your stuff in javascript. Serverside though you would need to access something external to your attribute class - the Request object - and that is a no no as far as I'm concerned.
All in all, there IS always a reason for things (not)happening and, in my opinion, a reason why Microsoft did not implement this kind of validator in a first place is - it is not possible without things described above.
BUT! I really hope I'm wrong. I DO need the compare validation to be easy to use...
I think you need something like this:
public class EqualsAttribute : ValidationAttribute
{
private readonly String _To;
public EqualsAttribute(String to)
{
if (String.IsNullOrEmpty(to))
{
throw new ArgumentNullException("to");
}
if (String.IsNullOrEmpty(key))
{
throw new ArgumentNullException("key");
}
_To = to;
}
protected override Boolean IsValid(Object value, ValidationContext validationContext, out ValidationResult validationResult)
{
validationResult = null;
var isValid = IsValid(value, validationContext);
if (!isValid)
{
validationResult = new ValidationResult(
FormatErrorMessage(validationContext.DisplayName),
new [] { validationContext.MemberName });
}
return isValid;
}
private Boolean IsValid(Object value, ValidationContext validationContext)
{
var propertyInfo = validationContext.ObjectType.GetProperty(_To);
if (propertyInfo == null)
{
return false;
}
var propertyValue = propertyInfo.GetValue(validationContext.ObjectInstance, null);
return Equals(value, propertyValue);
}
public override Boolean IsValid(Object value)
{
throw new NotSupportedException();
}
}

Categories

Resources