2010-02-19 6 views
11

Ich habe ein benutzerdefiniertes Attribut, innerhalb des Konstruktors meines benutzerdefinierten Attributs Ich möchte den Wert einer Eigenschaft meines Attributs auf den Typ der Eigenschaft festlegen, auf die mein Attribut angewendet wurde, gibt es eine Möglichkeit, auf das Element zuzugreifen, das das Attribut war angewendet auf von innerhalb meiner Attributklasse?Erhalten Mitglied, welches Attribut von innerhalb des Attributkonstruktors angewendet wurde?

+0

Können Sie kurz die Use-Case beschreiben? – Tanmay

+1

Wenn Sie das Problem, das Sie lösen, genauer beschreiben können, ist es möglicherweise möglich, eine alternative Lösung bereitzustellen. –

+1

Danke, ich weiß, wie ich das selbe auf andere Weise erreichen kann, aber ich wollte wissen, ob das möglich ist, weil der Code sauberer wäre. – ryudice

Antwort

13

Attribute funktionieren nicht so, fürchte ich. Sie sind lediglich "Marker", die an Objekten angebracht sind, aber nicht mit ihnen interagieren können.

Attribute selbst sollten in der Regel kein Verhalten aufweisen und lediglich Metadaten für den Typ enthalten, an den sie angehängt sind. Jedes mit einem Attribut verbundene Verhalten sollte von einer anderen Klasse bereitgestellt werden, die nach dem Vorhandensein des Attributs sucht und eine Aufgabe ausführt.

Wenn Sie an dem Typ interessiert sind, auf den das Attribut angewendet wird, stehen diese Informationen zur gleichen Zeit zur Verfügung, zu der Sie reflektieren, um das Attribut zu erhalten.

+0

Wie Sie sagen, ist es nicht das Ende der Welt, da Sie den Typ kennen, wenn Sie das benutzerdefinierte Attribut über Reflection erhalten, aber es wäre "nett", wenn der an GetCustomAttribute übergebene Type auch im System.Attribute gespeichert wäre –

0

Sie können als nächstes tun. Es ist ein einfaches Beispiel.

//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" 
     }; 
    } 
} 
0

Es ist möglich, von .NET 4.5CallerMemberName mit:

[SomethingCustom] 
public string MyProperty { get; set; } 

Dann wird Ihr Attribut:

[AttributeUsage(AttributeTargets.Property)] 
public class SomethingCustomAttribute : Attribute 
{ 
    public StartupArgumentAttribute([CallerMemberName] string propName = null) 
    { 
     // propName = "MyProperty" 
    } 
} 
Verwandte Themen