asp.net mvc एएसपीनेट एमवीसी-एक संग्रह के लिए प्रदर्शन टेम्पलेट




asp.net-mvc asp.net-mvc-3 (4)

मेरे पास एमवीसी में निम्नलिखित मॉडल है:

public class ParentModel
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }

    public IEnumerable<ChildModel> Children { get; set; }
}

जब मैं माता-पिता मॉडल के लिए सभी बच्चों को प्रदर्शित करना चाहता हूं तो मैं कर सकता हूं:

@Html.DisplayFor(m => m.Children)

इसके बाद मैं एक ChildModel.cshtml डिस्प्ले टेम्पलेट बना सकता हूं और DisplayFor स्वचालित रूप से सूची में फिर से चालू हो जाएगा।

अगर मैं IENumerable के लिए एक कस्टम टेम्पलेट बनाना चाहता हूं तो क्या होगा?

@model IEnumerable<ChildModel>

<table>
    <tr>
        <th>Property 1</th>
        <th>Property 2</th>
    </tr>
    ...
</table>

मैं एक डिस्प्ले टेम्पलेट कैसे बना सकता हूं जिसमें मॉडल प्रकार का IEnumerable<ChildModel> और उसके बाद @Html.DisplayFor(m => m.Children) को कॉल करें, इसके बिना मॉडल प्रकार गलत होने के बारे में शिकायत किए बिना?


यह मास्लो की टिप्पणी के जवाब में है। यह एसओ में मेरा पहला योगदान है, इसलिए मेरे पास टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा नहीं है - इसलिए उत्तर के रूप में उत्तर।

आप ModelMetadataProvider में 'TemplateHint' प्रॉपर्टी सेट कर सकते हैं। यह आपके द्वारा निर्दिष्ट टेम्पलेट में किसी भी आईनेमरेबल को ऑटो हुकअप करेगा। मैंने बस अपनी परियोजना में कोशिश की। नीचे कोड -

protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor)
    {
        var metaData = base.CreateMetadataFromPrototype(prototype, modelAccessor);
        var type = metaData.ModelType;

        if (type.IsEnum)
        {
            metaData.TemplateHint = "Enum";
        }
        else if (type.IsAssignableFrom(typeof(IEnumerable<object>)))
        {
            metaData.TemplateHint = "Collection";
        }

        return metaData;
    }

आप मूल रूप से 'CachedDataAnnotationsModelMetadataProvider' की 'CreateMetadataFromPrototype' विधि को ओवरराइड करते हैं और अपने व्युत्पन्न प्रकार को पसंदीदा मॉडलमैटाडाटाप्रोवाइडर के रूप में पंजीकृत करते हैं।

अपने टेम्पलेट में, आप सीधे अपने संग्रह में तत्वों के मॉडलमैटाडाटा तक नहीं पहुंच सकते हैं। मैंने अपने संग्रह में तत्वों के लिए ModelMetadata तक पहुंचने के लिए निम्न कोड का उपयोग किया -

@model IEnumerable<object>
@{ 
var modelType = Model.GetType().GenericTypeArguments[0];
var modelMetaData = ModelMetadataProviders.Current.GetMetadataForType(null, modelType.UnderlyingSystemType);

var propertiesToShow = modelMetaData.Properties.Where(p => p.ShowForDisplay);
var propertiesOfModel = modelType.GetProperties();

var tableData = propertiesOfModel.Zip(propertiesToShow, (columnName, columnValue) => new { columnName.Name, columnValue.PropertyName });
}

मेरे विचार में, मैं बस @ Html.DisplayForModel () को कॉल करता हूं और टेम्पलेट लोड हो जाता है। मॉडल पर 'UIHint' निर्दिष्ट करने की कोई आवश्यकता नहीं है।

मुझे आशा है कि यह कुछ मूल्य का था।


विचारों से आउटपुट प्राप्त करने के बारे में मेरे प्रश्न में, मेरे पास वास्तव में एक उदाहरण है कि मॉडल मॉडल को बाल मॉडल के संग्रह के साथ कैसे टेम्पलेट करें और उन्हें सभी प्रस्तुत करें।

एएसपी.नेट प्रदर्शन टेम्पलेट्स - कोई आउटपुट नहीं

अनिवार्य रूप से, आपको एक मॉडल बनाने की आवश्यकता है जो List<T> या Collection<T> subclasses और इसका उपयोग करें:

@model ChildModelCollection 

@foreach (var child in Model)
{
    Html.DisplayFor(m => child);
}

संग्रह मॉडल के लिए अपने टेम्पलेट में बच्चों को पुन: प्रस्तुत करने और प्रस्तुत करने के लिए। प्रत्येक बच्चे को मजबूती से टाइप करने की आवश्यकता होती है, इसलिए आप वस्तुओं के लिए अपने मॉडल प्रकार भी बनाना चाह सकते हैं, और उनके लिए टेम्पलेट भी ले सकते हैं।

तो ओपी प्रश्न के लिए:

public class ChildModelCollection : Collection<ChildModel> { }

एक दृढ़ता से टाइप मॉडल तैयार करेगा जो एक संग्रह है जिसे किसी अन्य टेम्पलेट के लिए हल किया जा सकता है।


वास्तविक "वैध उत्तर" -आईएमएचओ- प्रश्न का सही जवाब नहीं दे रहा है। मुझे लगता है कि ओपी एक सूची टेम्पलेट रखने का एक तरीका खोज रहा है जो UIHint निर्दिष्ट किए बिना ट्रिगर करता है।

जादू सामान लगभग नौकरी करता है

कुछ जादू निर्दिष्ट प्रकार के लिए सही दृश्य लोड करते हैं।
कुछ और जादू एक निर्दिष्ट प्रकार के संग्रह के लिए एक ही दृश्य लोड करता है
कुछ जादू होना चाहिए जो एक निर्दिष्ट प्रकार के संग्रह के लिए एक ही दृश्य को पुन: सक्रिय करता है।

वास्तविक व्यवहार बदलें?

अपना पसंदीदा डिस्सेबलर खोलें। जादू System.Web.Mvc.Html.TemplateHelpers.ExecuteTemplate में होता है। जैसा कि आप देख सकते हैं, व्यवहार को बदलने के लिए कोई विस्तारशीलता बिंदु नहीं है। शायद एमवीसी के लिए एक पुल अनुरोध मदद कर सकते हैं ...

वास्तविक जादू के साथ जाओ

मैं कुछ काम करता हूं जो काम करता है। एक प्रदर्शन टेम्पलेट ~/Views/Shared/DisplayTemplates/MyModel.cshtml प्रदर्शन टेम्पलेट ~/Views/Shared/DisplayTemplates/MyModel.cshtml

मॉडल object रूप में घोषित करें।

यदि ऑब्जेक्ट एक संग्रह है, तो फिर से टेम्पलेट को फिर से भरें और प्रस्तुत करें। यदि यह संग्रह नहीं है, तो ऑब्जेक्ट दिखाएं।

@model object

@if (Model is IList<MyModel>)
{
    var models = (IList<MyModel>)Model;
<ul>
    @foreach (var item in models)
    {
@Html.Partial("DisplayTemplates/MyModel", item)
    }
</ul>
} else {
    var item = (MyModel)Model;
    <li>@item.Name</li>
    }
}

अब DisplayFor UIHint बिना काम करता है।


इस कदर:

@Html.DisplayFor(m => m.Children, "YourTemplateName")

या इस तरह:

[UIHint("YourTemplateName")]
public IEnumerable<ChildModel> Children { get; set; }

जहां स्पष्ट रूप से आपके पास ~/Views/Shared/DisplayTemplates/YourTemplateName.cshtml :

@model IEnumerable<ChildModel>

<table>
    <tr>
        <th>Property 1</th>
        <th>Property 2</th>
    </tr>
    ...
</table>




display-templates