2013-03-05 7 views
7

मेरे पास ऐसे क्षेत्र हैं जो विभिन्न लोगों को अलग-अलग नामों में देखना चाहिए।क्या मैं एक ही क्षेत्र में कई बार IMetadataAware विशेषता का उपयोग कर सकता हूं?

उदाहरण के लिए, मैं निम्नलिखित उपयोगकर्ता प्रकार है लगता है:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 
public class DisplayForUserTypeAttribute : Attribute, IMetadataAware 
{ 
    private readonly UserType _userType; 

    public DisplayForUserTypeAttribute(UserType userType) 
    { 
     _userType = userType; 
    } 

    public string Name { get; set; } 

    public void OnMetadataCreated(ModelMetadata metadata) 
    { 
     if (CurrentContext.UserType != _userType) 
      return; 
     metadata.DisplayName = Name; 
    } 
} 

विचार यह है कि मैं अन्य मूल्यों के रूप में की जरूरत ओवरराइड कर सकते हैं, लेकिन वापस आते हैं:

public enum UserType {Expert, Normal, Guest} 

मैं एक IMetadataAware विशेषता कार्यान्वित डिफ़ॉल्ट मानों पर जब मैं नहीं करता हूं। उदाहरण के लिए:

public class Model 
{ 
    [Display(Name = "Age")] 
    [DisplayForUserType(UserType.Guest, Name = "Age (in years, round down)")] 
    public string Age { get; set; } 

    [Display(Name = "Address")] 
    [DisplayForUserType(UserType.Expert, Name = "ADR")] 
    [DisplayForUserType(UserType.Normal, Name = "The Address")] 
    [DisplayForUserType(UserType.Guest, Name = "This is an Address")] 
    public string Address { get; set; } 
} 

समस्या यह है कि जब मैं एक ही प्रकार के अनेक विशेषताएं है, DataAnnotationsModelMetadataProvider केवल चलाता है पहले एक के लिए OnMetadataCreated है।
उपर्युक्त उदाहरण में, Address केवल "पता" या "एडीआर" के रूप में दिखाया जा सकता है - अन्य विशेषताओं को कभी निष्पादित नहीं किया जाता है।

यदि मैं विभिन्न विशेषताओं - DisplayForUserType, DisplayForUserType2, DisplayForUserType3 का उपयोग करने का प्रयास करता हूं, तो सब कुछ अपेक्षित काम कर रहा है।

क्या मैं यहां कुछ भी गलत कर रहा हूं?

उत्तर

10

मैं जानता हूँ कि मैं थोड़ा के लिए देर से कर रहा हूँ यह पार्टी लेकिन मैं एक ही प्रश्न के उत्तर की तलाश में था और इसे वेब पर कहीं भी नहीं मिला। अंत में मैंने इसे खुद से बाहर किया।

संक्षिप्त उत्तर हाँ है, आप उसी प्रकार के कई विशेषताओं को प्राप्त कर सकते हैं जो उसी क्षेत्र/संपत्ति पर IMetadataAware इंटरफ़ेस को लागू करते हैं। आपको इसे विस्तारित करते समय विशेषता वर्ग के TypeId को ओवरराइड करना याद रखना होगा और इसे किसी ऐसी चीज़ से प्रतिस्थापित करना होगा जो आपको प्रत्येक व्युत्पन्न विशेषता के इंस्टेंस पर एक अद्वितीय ऑब्जेक्ट देगा।

यदि आप व्युत्पन्न विशेषता की TypeId प्रॉपर्टी को ओवरराइड नहीं करते हैं तो उस प्रकार के सभी विशेषताओं को वही माना जाता है क्योंकि डिफ़ॉल्ट कार्यान्वयन आईडी के रूप में विशेषता के रन टाइम प्रकार को लौटाता है।

तो निम्नलिखित अब काम करना चाहिए के रूप में वांछित:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 
public class DisplayForUserTypeAttribute : Attribute, IMetadataAware 
{ 
    private readonly UserType _userType; 

    public DisplayForUserType(UserType userType) 
    { 
     _userType = userType; 
    } 

    public override object TypeId 
    { 
     get 
     { 
      return this; 
     } 
    } 

    public string Name { get; set; } 

    public void OnMetadataCreated(ModelMetadata metadata) 
    { 
     if (CurrentContext.UserType != _userType) 
      return; 
     metadata.DisplayName = Name; 
    } 
} 
+0

मुझे 'TypeId' के बारे में पता नहीं था। यदि कोई दिलचस्पी लेता है तो यहां एक अच्छा स्पष्टीकरण दिया गया है: [क्या दो विशेषताओं के टाइप आईडी जो अर्थात् समान हैं समान या समान हैं?] (Http://stackoverflow.com/q/8728793/7586) बहुत बहुत धन्यवाद, और (देर हो चुकी है) ढेर ओवरफ्लो में आपका स्वागत है! – Kobi

+0

कोई चिंता नहीं, खुशी है कि मैं मदद कर सकता हूं - भले ही यह एक साल देर हो :-) –

+0

CurrentConte3xt अब और उपलब्ध नहीं है। क्या एमवीसी 5 और उच्चतर में कुछ हासिल करना संभव है? –

1

आप कार्यान्वयन गलत नहीं है, लेकिन IMetadataAware लागू करने वाली कोई भी विशेषता मेटाडाटा निर्माण के बाद AssociatedMetadataProvider (और किसी भी व्युत्पन्न प्रकार) द्वारा लागू की जाती है। डिफ़ॉल्ट व्यवहार को ओवरराइड करने के लिए, आप कस्टम ModelMetadataProvider लागू कर सकते हैं।

DisplayForUserType वर्ग से इंटरफ़ेस IMetadataAware निकालें:

यहाँ एक और वैकल्पिक त्वरित समाधान है।

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 
    public class DisplayForUserTypeAttribute : Attribute//, IMetadataAware 
    { 
     //your existing code... 
    } 

एक नई IMetadataAware विशेषता है कि प्रयोक्ता प्रकार से प्रदर्शन तर्क लागू होगा, नीचे के रूप में परिभाषित करें:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 
    public class ApplyDisplayForUserTypeAttribute : Attribute, IMetadataAware 
    { 
     private readonly string _property; 
     public ApplyDisplayForUserTypeAttribute(string property) 
     { 
      this._property = property; 
     } 

     public void OnMetadataCreated(ModelMetadata metadata) 
     { 
      var attribues = GetCustomAttributes(metadata.ContainerType 
                 .GetProperty(this._property), typeof(DisplayForUserTypeAttribute)) 
                 .OfType<DisplayForUserTypeAttribute>().ToArray(); 
      foreach (var displayForUserTypeAttribute in attribues) 
      { 
       displayForUserTypeAttribute.OnMetadataCreated(metadata); 
      } 
     } 
    } 

और मॉडल होगा:

public class Model 
    { 
     [Display(Name = "Age")] 
     [DisplayForUserType(UserType.Guest, Name = "Age (in years, round down)")] 
     [ApplyDisplayForUserType("Age")] 
     public string Age { get; set; } 

     [Display(Name = "Address")] 
     [DisplayForUserType(UserType.Expert, Name = "ADR Expert")] 
     [DisplayForUserType(UserType.Normal, Name = "The Address Normal")] 
     [DisplayForUserType(UserType.Guest, Name = "This is an Address (Guest)")] 
     [ApplyDisplayForUserType("Address")] 
     public string Address { get; set; } 
    } 
+0

धन्यवाद!दरअसल, मेरे पास पहले से ही एक त्वरित फिक्स है - मैंने 'DisplayForExpertUser',' DisplayForNormalUser' और 'DisplayForGuestUser' परिभाषित किया है - जो बहुत अच्छी तरह से काम कर रहा है। – Kobi

+0

मैं वास्तव में पहली वाक्य को नहीं समझता: "मेटाडेटा निर्माण के बाद एसोसिएटेड मेटाडाटा प्रदाता (और किसी भी व्युत्पन्न प्रकार) द्वारा IMetadataAware लागू करने वाली कोई भी विशेषता लागू होती है" - यदि यह मामला था, तो इसे काम करना चाहिए था। मैं जो व्यवहार देखता हूं वह एक बग जैसा दिखता है, लेकिन मैं निष्कर्ष पर कूदना नहीं चाहता - क्या आप सुझाव दे रहे हैं कि एक अच्छी व्याख्या है? – Kobi

संबंधित मुद्दे

 संबंधित मुद्दे