अशक्त मॉडल के साथ रेंडरशिपियल गलत प्रकार से गुजरता है


198

मेरे पास एक पृष्ठ है:

<%@ Page Inherits="System.Web.Mvc.View<DTOSearchResults>" %>

और उस पर, निम्नलिखित:

<% Html.RenderPartial("TaskList", Model.Tasks); %>

यहाँ DTO ऑब्जेक्ट है:

public class DTOSearchResults
{
    public string SearchTerm { get; set; }
    public IEnumerable<Task> Tasks { get; set; }

और यहाँ आंशिक है:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Task>>" %>

जब Model.Tasks शून्य नहीं है, तो सब कुछ ठीक काम करता है। हालांकि जब इसकी अशक्तता मुझे मिलती है:

डिक्शनरी में पास किया गया मॉडल आइटम 'DTOSearchResults' प्रकार का है, लेकिन इस शब्दकोश में 'System.Collections.Generic.IEnumerable`1 [Task]' टाइप के मॉडल आइटम की आवश्यकता होती है।

मुझे लगा कि यह पता नहीं होना चाहिए कि किस ओवरलोड का उपयोग करना है, इसलिए मैंने स्पष्ट होने के लिए ऐसा किया (नीचे देखें), लेकिन मुझे अभी भी वही मुद्दा मिला है!

<% Html.RenderPartial("TaskList", (object)Model.Tasks, null); %>

मुझे पता है कि मैं इसके लिए अशक्त की जाँच करके काम कर सकता हूं, या अशक्त गुजरने पर भी नहीं, लेकिन यह बात नहीं है। ये क्यों हो रहा है?

जवाबों:


349

एंड्रयू मुझे लगता है कि आपको जो समस्या हो रही है, वह कॉलिंग (दृश्य) मॉडल के आंशिक दृश्य का उपयोग करने के दौरान रेंडरप्रार्टियल पद्धति का परिणाम है जब आप पास होने वाले मॉडल को शून्य मानते हैं .. तो आप इस अजीब व्यवहार को कर सकते हैं:

<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary()); %>

क्या उससे मदद हुई?


16
फिर भी लोगों का समय बच रहा है। मैं इस पर अपने बाल खींच रहा था।
जेम्स ग्रेगरी

3
मुझे लगता है कि वे क्यों अशक्त मॉडल का समर्थन करते हैं और पृष्ठों को पारित करते हैं मॉडल लेकिन क्या वे इसे ओवरलोडिंग द्वारा नियंत्रित नहीं कर सकते थे। @ Html.Render ("गदहे") @ Html.Render ("गदहे" से अलग है, सकता है)
फिल स्ट्रांग

19
मुझे यह बहुत अच्छा लगता है इसलिए मैंने एक "मुद्दा" जोड़ा, अगर आप सहमत हैं तो इस पर वोट करें: aspnet.codeplex.com/workitem/8872
pbz

3
मैंने पाया कि इस समाधान के साथ मेरे आंशिक दृश्य में मेरे सत्यापन का कार्य नहीं हुआ क्योंकि प्राथमिक मॉडल का व्यूडेटा आंशिक दृश्य में खो गया था। मैंने इसे हल करने के लिए यहां दिए गए उत्तर stackoverflow.com/a/12037580/649497 का उपयोग किया ।
ब्रूसहिल

5
आपको मौजूदा ViewData के साथ पास होना चाहिए: नया ViewDataDictionary (ViewData)
स्कॉट जूल

48

@ myandmycode का जवाब अच्छा है, लेकिन थोड़ा कम होगा

<% Html.RenderPartial("TaskList", new ViewDataDictionary(Model.Tasks)); %>

यह काम करता है क्योंकि वह ViewDataDictionaryचीज है जो मॉडल रखती है, और यह एक मॉडल को कंस्ट्रक्टर पैरामीटर के रूप में स्वीकार कर सकता है। यह मूल रूप से एक "संपूर्ण" व्यू डेटा डिक्शनरी से गुजरता है, जिसमें निश्चित रूप से केवल संभवतः-शून्य मॉडल शामिल है।


2
@jcmcbeth: एर्म, नहीं, यह नहीं है ... मैंने नल के साथ इस सटीक कोड का सफलतापूर्वक उपयोग किया है।
विन्यासकर्ता

1
@jcmcbeth: क्या आप उपयोग कर रहे हैं new ViewDataDictionary(null)? क्योंकि वह एक अलग अधिभार उठाएगा, एक ViewDataDictionaryपैरामीटर के साथ , जो शायद नल को स्वीकार नहीं करेगा।
विन्यासकर्ता

1
ऐसा प्रतीत होता है कि ViewBag संपत्ति का उपयोग करने से गलत निर्माणकर्ता को बुलाया जाता है। यह एक डायनामिक प्रकार कैसे लेता है और मानता है कि यह एक दृश्य पर एक दृश्य पर मुझे कोई मतलब नहीं है, लेकिन यह प्रतीत होता है कि यह क्या कर रहा है। सही कंस्ट्रक्टर का चयन करने के लिए आपको इसे एक ऑब्जेक्ट में डालना होगा।
जोएल मैकबेथ

1
@jcmcbeth: इसे डायनेमिक प्रकार पर कॉल करना उसी तरह उपयोग करता है जैसे आपने वास्तविक मूल्य दिया है; यदि मान है null, तो यह कॉलिंग के समान है new ViewDataDictionary(null)जो सबसे विशिष्ट अधिभार का कारण बनता है।
विन्यासकर्ता

1
यदि आप इसे इस तरह से उपयोग करते हैं, तो डिक्शनरी त्रुटि हो गई है .. Html.RenderPartial("TaskList", new ViewDataDictionary(model: Model.Tasks))यदि आप गलत कंस्ट्रक्टर का उपयोग कर रहे हैं, तो यह शून्य है।
फिलिप कॉर्नेलिसन

26

ऐसा प्रतीत होता है कि जब आप जिस मॉडल से गुजर रहे हैं उसकी संपत्ति शून्य MVC जानबूझकर "मूल" मॉडल पर वापस लौट जाती है। जाहिरा तौर पर MVC इंजन पिछले मॉडल का उपयोग करने के इरादे के रूप में एक अशक्त मॉडल मूल्य की व्याख्या करता है।

यहाँ थोड़ा अधिक विवरण: ASP.NET MVC, दृढ़ता से टाइप किए गए विचार, आंशिक दृश्य पैरामीटर गड़बड़


1
+1 वास्तव में इस मुद्दे को समझाने की कोशिश कर रहा है, और न केवल इसे एक अजीब व्यवहार के रूप में
मान रहा है

हां, यह मेरे साथ हो रहा था और ऊपर ने इसे ठीक नहीं किया, इसने मुझे मेरी वास्तविक त्रुटि के बारे में कुछ और जानकारी दी।
कैनवस

20

यदि आप आंशिक दृश्य में अपने पिछले ViewData को ढीला नहीं करना चाहते हैं, तो आप कोशिश कर सकते हैं:

<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary(ViewData){Model = null});%>

1
इस सवाल का जवाब नहीं लगता है।
जॉन सौन्डर्स

6
+1 वास्तव में यह काम करता है। यह मूल रूप से एक ही विचार है जिसे यहां प्रस्तुत किया गया है stackoverflow.com/a/713921/649497, लेकिन उस उत्तर के साथ एक समस्या पर काबू पा लेता है और वह यह है कि यदि आप एक खाली कंस्ट्रक्टर के साथ ViewDataDictionary को तुरंत देखते हैं तो ViewData गायब हो जाएगा। मैंने पहली बार इस समस्या को स्वीकृत समाधान के साथ हल किया और फिर पाया कि मेरी मान्यताएं आंशिक दृष्टिकोण में काम नहीं करती हैं। यह समाधान मेरे लिए हल हो गया। इस उत्तर को समस्या को हल करने और अपने आंशिक दृश्य में ViewData को संरक्षित करने के लिए अधिक मान्यता की आवश्यकता है।
ब्रूसहिल

1
@Franc P ने वास्तव में ViewBag मूल्यों को खोए बिना काम किया और इसलिए एक अशक्त मॉडल पारित किया। धन्यवाद।
ज़कर नोव

यह सही उत्तर है यदि आपको अपने धारावाहिकों में व्यूबग एक्सेस की आवश्यकता है!
डैनियल लोरेंज

12

इस तरह एक HtmlHelper बनाने के लिए एक समाधान होगा:

public static MvcHtmlString Partial<T>(this HtmlHelper htmlHelper, string partialViewName, T model)
{
    ViewDataDictionary viewData = new ViewDataDictionary(htmlHelper.ViewData)
    {
        Model = model
    };
    return PartialExtensions.Partial(htmlHelper, partialViewName, model, viewData);
}

Partial<T>(...)पहले से मिलान किया Partial(...)तो सुविधाजनक और कोई अस्पष्टता नहीं त्रुटि संकलन।

व्यक्तिगत रूप से मुझे व्यवहार को समझना मुश्किल लगता है - डिजाइन विकल्प के रूप में यह कल्पना करना मुश्किल लगता है?


1
मैंने अंत में यही किया। asp.net mvc में कई डिज़ाइन विकल्प / व्यवहार नहीं हैं जो किसी भी अर्थ में हैं। चूंकि इसे छोड़ दिया। दूसरों के लिए उपयोगी है, इसलिए
एंड्रयू बुलॉक

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

11

यद्यपि इसका उत्तर दिया गया है, मैं इस पार गया और निर्णय लिया कि मैं इस परियोजना के लिए इस मुद्दे को हल करने के बजाय इसके साथ काम करना चाहता हूं new ViewDataDictionary()

मैंने एक्सटेंशन विधियों का एक सेट बनाया: https://github.com/q42jaap/PartialMagic.Mvc/blob/master/PartialMagic.Mvc/PartialExtensions.cs
मैंने कुछ ऐसे तरीके भी जोड़े हैं जो मॉडल के अशक्त होने पर आंशिक कॉल नहीं करते हैं , यह बहुत सारे अगर बयानों को बचाएगा।

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

विस्तार के तरीके इस तरह दिखते हैं:

@* calls the partial with Model = null *@
@Html.PartialOrNull("PartialName", null)
@* does not call the partial if the model is null *@
@Html.PartialOrDiscard("PartialName", null)

IEnumerable<object>मॉडल के लिए तरीके भी हैं और त्यागने वालों को रेजर लैम्ब्डा के साथ भी बुलाया जा सकता है जो आपको कुछ HTML के साथ आंशिक परिणाम लपेटने की अनुमति देता है।

यदि आप चाहें तो उनका उपयोग करने के लिए स्वतंत्र महसूस करें।


1
MVC5 के रूप में अभी भी उपयोगी है: 6/25/2014। धन्यवाद।
जेसन

1

इसके लिए मेरा काम है:


<% Html.RenderPartial("TaskList", Model.Tasks ?? new List()); %>


यह एक गंदा उपाय है। अपने आंशिक दृष्टिकोण पर, आपको यह जाँचने में सक्षम होना चाहिए कि सूची में कोई मान है या नहीं और यदि यह अशक्त है तो जाँच करने के बजाय।
MADD
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.