Brandon Linton
Brandon Linton

Reputation: 4411

How can I retrieve the instance of an attribute's associated object?

I'm writing a PropertiesMustMatch validation attribute that can take a string property name as a parameter. I'd like it to find the corresponding property by name on that object and do a basic equality comparison. What's the best way to access this through reflection?

Also, I checked out the Validation application block in the Enterprise Library and decided its PropertyComparisonValidator was way too intense for what we need.

UPDATE: For further clarification (to provide some context), the goal is simply validation that enforces field matching (e.g., password verification). We'd like it to work with property-level attribute data annotations that inherit from the ValidationAttribute class, if possible.

UPDATE: In case anyone is curious, I ended up solving the actual business problem through tweaking code provided as an answer to this question

Upvotes: 3

Views: 4575

Answers (3)

Klyuch
Klyuch

Reputation: 64

You can something like this.

//target class
public class SomeClass{

  [CustomRequired(ErrorMessage = "{0} is required", ProperytName = "DisplayName")]
  public string Link { get; set; }

  public string DisplayName { get; set; }
}
//custom attribute
public class CustomRequiredAttribute : RequiredAttribute, IClientValidatable
{
  public string ProperytName { get; set; }

  public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
  {
    var propertyValue = "Value";
    var parentMetaData = ModelMetadataProviders.Current
         .GetMetadataForProperties(context.Controller.ViewData.Model, context.Controller.ViewData.Model.GetType());
    var property = parentMetaData.FirstOrDefault(p => p.PropertyName == ProperytName);
    if (property != null)
        propertyValue = property.Model.ToString();

    yield return new ModelClientValidationRule
    {
        ErrorMessage = string.Format(ErrorMessage, propertyValue),
        ValidationType = "required"
    };
  }
}

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1062600

You can't, basically. The code that checks the object for the presence of the attribute must also assume responsibility for telling any code which type/object it was looking at. You can't obtain any additional metadata from within an attribute.

Upvotes: 5

wRAR
wRAR

Reputation: 25693

You cannot do that. See also this question. Try to change the logic to work with the object, checking its attributes, not vice versa. You can also provide more information about your task, not just this narrow question.

Upvotes: 1

Related Questions