DisplayNameFor () सूची से <ऑब्जेक्ट> मॉडल में


87

मेरा मानना ​​है कि यह बहुत आसान है, मैं सिर्फ अपने मॉडल के भीतर एक सूची के लिए एक आइटम के लिए प्रदर्शन नाम दिखाने का सही तरीका नहीं खोज सकता।

मेरा सरलीकृत मॉडल:

public class PersonViewModel
{
    public long ID { get; set; }

    private List<PersonNameViewModel> names = new List<PersonNameViewModel>();

    [Display(Name = "Names")]
    public List<PersonNameViewModel> Names { get { return names; } set { names = value; } }      
}

और नाम:

public class PersonNameViewModel
{
    public long ID { get; set; }

    [Display(Name = "Set Primary")]
    public bool IsPrimary { get; set; }

    [Display(Name = "Full Name")]
    public string FullName { get; set; }
}

अब मैं किसी व्यक्ति के सभी नामों को दिखाने के लिए एक तालिका बनाना चाहूंगा, और DisplayNameFor FullName प्राप्त करूंगा। जाहिर है,

@Html.DisplayNameFor(model => model.Names.FullName);

काम नहीं करेगा, और

@Html.DisplayNameFor(model => model.Names[0].FullName);  

अगर कोई नाम नहीं है तो टूट जाएगा। क्या यहां प्रदर्शन नाम प्राप्त करने का कोई 'सबसे अच्छा तरीका' है?

जवाबों:


143

यह वास्तव में सूची में आइटम के बिना भी काम करता है:

@Html.DisplayNameFor(model => model.Names[0].FullName)

यह काम करता है क्योंकि एमवीसी वास्तव में इसे निष्पादित करने के बजाय अभिव्यक्ति को पार्स करता है। इससे यह पता चलता है कि सूची में एक तत्व होने की आवश्यकता के बिना सही संपत्ति और विशेषता है।

यह ध्यान देने योग्य है कि पैरामीटर ( modelऊपर) का भी उपयोग करने की आवश्यकता नहीं है। यह भी काम करता है:

@Html.DisplayNameFor(dummy => Model.Names[0].FullName)

जैसा कि यह है:

@{ Namespace.Of.PersonNameViewModel dummyModel = null; }
@Html.DisplayNameFor(dummyParam => dummyModel.FullName)

मैं मान रहा हूँ कि यदि आपके बजाय List<PersonNameViewModel>एक है IEnumerable<PersonNameViewModel>, तो यह अभिव्यक्ति का उपयोग करने के लिए भी सुरक्षित है model => model.Names.First().FullName। क्या ये सही है? उस ने कहा, मुझे लगता है कि मुझे dummyModelतीनों में से उदाहरण सबसे अच्छा लगता है । अन्यथा, आपके पास कई गुण हो सकते हैं जहाँ आपको टाइप या पेस्ट करने की आवश्यकता होती है model.Names[0].। तो फिर, शायद आपको अनुभाग को आंशिक दृष्टिकोण के लिए फिर से भरना चाहिए जो कि Listया IEnumerableइसके मॉडल के रूप में स्वीकार करता है ।
अहांतोइन

6
मैंने परीक्षण किया और FirstOrDefault()एक खाली सूची के साथ काम करता है।
जोश के

दुर्भाग्य से यह IEnumerable संपत्ति पर काम नहीं करता है।
विली डेविड जूनियर

7

इसे करने का एक और तरीका है, और मुझे लगता है कि यह अधिक स्पष्ट है:

public class Model
{
    [Display(Name = "Some Name for A")]
    public int PropA { get; set; }

    [Display(Name = "Some Name for B")]
    public string PropB { get; set; }
}

public class ModelCollection
{
    public List<Model> Models { get; set; }

    public Model Default
    {
        get { return new Model(); }
    }
}

और फिर, दृश्य में:

@model ModelCollection

<div class="list">
    @foreach (var m in Model.Models)
    {
        <div class="item">
            @Html.DisplayNameFor(model => model.Default.PropA): @m.PropA
            <br />
            @Html.DisplayNameFor(model => model.Default.PropB): @m.PropB
        </div>
    }
</div>

1

मुझे टी-मोटी का घोल पसंद है। मुझे जेनरिक का उपयोग करते हुए एक समाधान की आवश्यकता थी ताकि मेरा समाधान अनिवार्य रूप से यह हो:

public class CustomList<T> : List<T> where T : new()
{       
    public static async Task<CustomList<T>> CreateAsync(IQueryable<T> source)
    {           
        return new CustomList<T>(List<T> list); //do whatever you need in the contructor, constructor omitted
    }

    private T defaultInstance = new T();

    public T Default
    {
        get { return defaultInstance; }
    }
}

दृश्य में इसका उपयोग करना उसके उदाहरण के समान है। मैं एक खाली वस्तु का एक ही उदाहरण बनाता हूं इसलिए मैं डिफ़ॉल्ट रूप से हर बार एक नया उदाहरण नहीं बना रहा हूं ।

ध्यान दें, नए T () को कॉल करने के लिए नए () अवरोध की आवश्यकता है । यदि आपके मॉडल वर्ग में डिफ़ॉल्ट अवरोधक नहीं है, या आपको कंस्ट्रक्टर में तर्क जोड़ने की आवश्यकता है तो आप इसका उपयोग कर सकते हैं:

private T defaultInstance = (T)Activator.CreateInstance(typeof(T), new object[] { "args" });

दृश्य में @model लाइन होगी जैसे:

@model CustomList<Namespace.Of.PersonNameViewModel.Model>

ध्यान दें कि DisplayNameForवास्तव getमें संपत्ति के लिए कभी भी कॉल नहीं किया जाता है, इसलिए यदि आप एक उदाहरण बनाते हैं तो यह कोई फर्क नहीं पड़ता।
नेटमैज

1

एक वैकल्पिक समाधान के रूप में आप कोशिश कर सकते हैं:

@Html.DisplayNameFor(x => x.GetEnumerator().Current.ItemName)

सूची खाली होने पर भी यह काम करेगा!


मुझे टिम एस के समाधान के बजाय इस समाधान का उपयोग क्यों करना चाहिए?
EKanadily
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.