2010-03-31 10 views
17

आज जब ASP.NET MVC 2 में <%=Html.LabelFor(m=>m.MyProperty)%> के एक जोड़े कर रहे हैं और System.ComponentModel से [DisplayName("Show this instead of MyProperty")] विशेषता का उपयोग मैं उलझन में मिल गया।सोच

जैसा कि यह निकला, जब मैंने ओवरराइड संपत्ति पर विशेषता डाली, तो लेबलफ़ोर को यह नोटिस नहीं हुआ।
हालांकि, [Required] विशेषता ओवरराइड संपत्ति पर ठीक काम करती है, और जेनरेट की गई त्रुटि वास्तव में DisplayNameAttribute का उपयोग करती है।

यह कुछ मामूली उदाहरण कोड है, और यथार्थवादी परिदृश्य यह है कि मेरे पास एक डाटाबेसमोडेल व्यूमोडेल से अलग है, लेकिन सुविधा के लिए, मैं डेटाबेसबेस से प्राप्त करना चाहता हूं, केवल-देखने के गुणों को जोड़ना चाहता हूं और व्यूमोडेल को सजाने के साथ यूआई के लिए विशेषताएं।

public class POCOWithoutDataAnnotations 
{ 
    public virtual string PleaseOverrideMe { get; set; }   
} 
public class EditModel : POCOWithoutDataAnnotations 
{ 
    [Required] 
    [DisplayName("This should be as label for please override me!")] 
    public override string PleaseOverrideMe 
    { 
     get { return base.PleaseOverrideMe; } 
     set { base.PleaseOverrideMe = value; } 
    } 

    [Required] 
    [DisplayName("This property exists only in EditModel")] 
    public string NonOverriddenProp { get; set; } 
} 

दृढ़ता से टाइप किया ViewPage<EditModel> शामिल हैं:

 <div class="editor-label"> 
      <%= Html.LabelFor(model => model.PleaseOverrideMe) %> 
     </div> 
     <div class="editor-field"> 
      <%= Html.TextBoxFor(model => model.PleaseOverrideMe) %> 
      <%= Html.ValidationMessageFor(model => model.PleaseOverrideMe) %> 
     </div> 

     <div class="editor-label"> 
      <%= Html.LabelFor(model => model.NonOverriddenProp) %> 
     </div> 
     <div class="editor-field"> 
      <%= Html.TextBoxFor(model => model.NonOverriddenProp) %> 
      <%= Html.ValidationMessageFor(model => model.NonOverriddenProp) %> 
     </div> 

लेबल तो के रूप में "PleaseOverrideMe" (नहीं DisplayNameAttribute प्रयोग करके) और प्रदर्शित किए जाते हैं "यह संपत्ति केवल EditModel में मौजूद है" (पृष्ठ को देखते समय DisplayNameAttribute) का उपयोग कर।
अगर मैं खाली मूल्यों के साथ पोस्ट, इस ActionMethod साथ सत्यापन ट्रिगर:

[HttpPost] 
    public ActionResult Edit(EditModel model) 
    { 
     if (!ModelState.IsValid) 
      return View(model); 
     return View("Thanks"); 
    } 

<%= Html.ValidationMessageFor(model => model.PleaseOverrideMe) %> वास्तव में उपयोग करता [DisplayName("This should be as label for please override me!")] विशेषता, और डिफ़ॉल्ट errortext पैदा करता है "यह लेबल के रूप में किया जाना चाहिए के लिए कृपया मुझे ओवरराइड क्षेत्र है! की आवश्यकता है। "

क्या कुछ दोस्ताना आत्मा इस पर कुछ प्रकाश डालती है?

+0

लासे, आप अंतरिम में किसी भी भाग्य पड़ा है? –

+0

यदि आप अपनी सभी संपत्तियों को प्रदर्शित करने के लिए प्रतिबिंब का उपयोग कर रहे हैं तो आपके पास 'ModelMetadata' प्रकार उपलब्ध है। अनिवार्य रूप से आप यह 'HTML.Label (prop.GetDisplayName()) करेंगे। –

उत्तर

11

Model binding and metadata using the strongly-typed helpers looks at the declared, rather than the runtime, type of the model। मैं इसे एक बग मानता हूं, लेकिन स्पष्ट रूप से एमवीसी टीम मुझसे असहमत है, क्योंकि इस पर मेरा कनेक्ट इश्यू "डिजाइन द्वारा" बंद कर दिया गया था।

+4

ठीक है, मैं इसे एक बग @ कनेक्ट के रूप में दर्ज करने का प्रयास करूंगा और फिर "डिज़ाइन द्वारा" तैयार रहूंगा। धन्यवाद! –

+0

कोई बग नहीं है? मैंने अपनी पूरी परियोजना एमवीसी 3 में ले जाया और यह मेरी तरफ दर्द है। यह ठीक काम करता था - क्या प्रदर्शन नाम विशेषता अब इस तरह काम नहीं करनी चाहिए? – Jack

+0

तो जब आप संपादन/प्रदर्शन ऑब्जेक्ट टेम्पलेट को ओवरराइड करते हैं और 'Html.EditorForModel' का उपयोग करते हैं तो क्या होता है? अपने टेम्पलेट के भीतर आप 'Html.Label() 'का उपयोग करते हैं और आप प्रदर्शन विशेषता पर नहीं पहुंच सकते हैं। डिजाइन द्वारा? क्या उन्होंने आईई टीम से मूर्खों को किराए पर लिया? –

2

मेरे पास एक ही समस्या थी जब मेरे पास एक इंटरफ़ेस को दृढ़ता से टाइप किया गया आंशिक दृश्य था। इंटरफेस ने DisplayName परिभाषित किया और इंटरफ़ेस को लागू करने वाली कक्षा ने इसे ओवरराइड करने का प्रयास किया। ओवरराइड का सम्मान करने के लिए मुझे मिलने का एकमात्र तरीका कार्यान्वयन वर्ग को टाइप करना था। मुझे या तो दृश्य के मॉडल प्रकार या कास्ट बदलना पड़ा। दुर्भाग्यवश, यह मॉडल प्रकार के रूप में इंटरफ़ेस का उपयोग करने के लाभों को पूरी तरह से अस्वीकार करता है। मैं अनुमान लगा रहा हूं कि दृढ़ता से टाइप किए गए "हेल्पर्स" के भीतर कास्टिंग नहीं करते समय मैं प्रत्येक कार्यान्वयन वर्ग के लिए डुप्लिकेट व्यू मार्कअप के कुछ स्तर के साथ समाप्त हो जाऊंगा।

दूरस्थ अवसर में इस प्रकार का कामकाज भी दूरस्थ रूप से सहायक है (मेरी उम्मीद नहीं मिल रहा है), यहां एक उदाहरण है। नामों को ओवरराइड करने का प्रयास करने वाले सभी संभावित कार्यान्वयन वर्गों के लिए इसमें काम करने के निश्चित तरीके हैं, लेकिन यह निश्चित रूप से इससे अधिक परेशानी होना चाहिए।

public interface IAddressModel { 
    ... 
    [DisplayName("Province")] 
    public string Province { get; set; } 
    ... 
} 
public class UsAddressModel : IAddressModel { 
    ... 
    [DisplayName("State")] 
    public string Province { get; set; } 
    ... 
} 

<%= Html.LabelFor(m => m.State) %> <!--"Province"--> 
<%= Html.LabelFor(m => (m as UsAddressModel).State) %> <!--"State"--> 
11

मैं इस समस्या का उपयोग कर [DisplayName ("प्रोफ़ाइल नाम")] में पड़ गए और बजाय [Display(Name = "Profile Name")] जो मेरे मामले में समस्या तय किया करते थे। मुझे यकीन नहीं है कि यह उपयोगी होगा।

पूर्व System.ComponentModel से है जबकि बाद वाला System.ComponentModel.DataAnnotations है।

+3

छह साल बाद, यह एमवीसी 5 में एक ही समस्या तय की गई :) – pmbanka

+1

+ सात। कोर एमवीसी * अंगूठे में फिक्स्ड * –

3

ठीक है, अगर आप इसके साथ आवश्यक टैग का उपयोग नहीं करते हैं, तो मुझे लगता है कि एक कामकाज मिल गया है! वैध प्रविष्टि है या नहीं, यह निर्धारित करने के लिए बस एक नियमित अभिव्यक्ति या लंबाई विशेषता का उपयोग करें। उम्मीद है कि यह मदद करता है, हालांकि यह थोड़ा देर हो चुकी है।

[RegularExpression(@"^[1-9][0-9][0-9]$")] //validates that there is at least 1 in the quantity and no more than 999 
[DisplayName("Quantity:")] 
public string quantity { get; set; } 

अभी भी काम करता है।

3

मेरे मामले में मैं इसे गेटर्स और सेटर्स का उपयोग करके एक संपत्ति बनाने के लिए भूल गया था।

public string CompanyName; 

के बजाय मैं का इस्तेमाल किया है चाहिए

public string CompanyName {get;set;} 
संबंधित मुद्दे