2011-12-27 7 views
33
सुई

इस सरल नियंत्रक पर विचार जाँच हो रही है:अगर ViewBag एक संपत्ति है या नहीं यह देखने के लिए, सशर्त जावास्क्रिप्ट

Porduct product = new Product(){ 
    // Creating a product object; 
}; 
try 
{ 
    productManager.SaveProduct(product); 
    return RedirectToAction("List"); 
} 
catch (Exception ex) 
{ 
    ViewBag.ErrorMessage = ex.Message; 
    return View("Create", product); 
} 

अब, मेरी Create ध्यान में रखते हुए, मैं अगर यह Error को देखने के लिए ViewBag वस्तु की जांच करना चाहते हैं संपत्ति या नहीं। अगर इसमें त्रुटि संपत्ति है, तो मुझे अपने उपयोगकर्ता को त्रुटि संदेश दिखाने के लिए, पृष्ठ में कुछ जावास्क्रिप्ट इंजेक्ट करने की आवश्यकता है।

मैं एक विस्तार विधि बनाई गई इस जांच करने के लिए:

public static bool Has (this object obj, string propertyName) 
{ 
    Type type = obj.GetType(); 
    return type.GetProperty(propertyName) != null; 
} 

फिर, Create ध्यान में रखते हुए, मैं कोड की इस पंक्ति ने लिखा है:

@if (ViewBag.Has("Error")) 
{ 
    // Injecting JavaScript here 
} 

हालांकि, मैं इस त्रुटि मिलती है:

Cannot perform runtime binding on a null reference

कोई विचार?

+0

'ViewBag' रिक्त है? –

+0

वास्तव में कौन सा कोड उस त्रुटि को उत्पन्न कर रहा है? –

+0

@ जॉन सैंडर्स, जैसा कि आप देखते हैं कि मैंने अपने नियंत्रक में 'ViewBag.Error' सेट किया है? यह कैसे शून्य हो सकता है? –

उत्तर

20

आपका कोड काम नहीं करता है क्योंकि ViewBag एक dynamic object एक 'असली' प्रकार नहीं है।

निम्नलिखित कोड काम करना चाहिए:

public static bool Has (this object obj, string propertyName) 
{ 
    var dynamic = obj as DynamicObject; 
    if(dynamic == null) return false; 
    return dynamic.GetDynamicMemberNames().Contains(propertyName); 
} 
+0

अच्छा सुझाव @ जेफरीएबेकर देखें। धन्यवाद, लेकिन मुझे 'शून्य संदर्भ' अपवाद पर रनटाइम बाध्यकारी निष्पादित नहीं किया जा सकता है। –

+3

लगता है कि मुझे इसका उपयोग '((ऑब्जेक्ट) व्यूबैग) जैसे करना चाहिए। (" संपत्ति नाम ")'। –

+0

रिशेर्पर सुझाव देता है "वापसी गतिशील! = शून्य और गतिशील। GetDynamicMemberNames()। (PropertyName) शामिल है;" पिछले 2 लाइनों के बजाय। अच्छा समाधान! धन्यवाद! –

3

मैं पूरी तरह से व्यूबैग से बचूंगा। इस पर मेरे विचार यहां देखें: http://completedevelopment.blogspot.com/2011/12/stop-using-viewbag-in-most-places.html

विकल्प एक कस्टम त्रुटि फेंकने और इसे पकड़ने के लिए होगा। आप कैसे जानते हैं कि डेटाबेस डाउन है, या यदि यह एक व्यावसायिक तर्क त्रुटि को बचाता है? उपर्युक्त उदाहरण में आप केवल एक अपवाद पकड़ते हैं, आम तौर पर प्रत्येक अपवाद प्रकार को पकड़ने के लिए एक बेहतर तरीका है, और उसके बाद वास्तव में अनचाहे अपवादों के लिए एक सामान्य अपवाद हैंडलर जैसे कि कस्टम त्रुटि पृष्ठों में निर्मित या ELMAH का उपयोग करना।

तो ऊपर, मैं करूंगा बजाय ModelState.AddModelError() फिर आप इन त्रुटियों को देख सकते हैं (यह मानते हुए आप सिर्फ मान्यता में बनाया का उपयोग करने जा रहे हैं) के माध्यम से How do I access the ModelState from within my View (aspx page)?

तो ध्यान से एक को प्रदर्शित करने पर विचार करें जब आप 'कोई' अपवाद पकड़ते हैं तो संदेश।

+0

ऐसा लगता है कि मैं "necrothreading" हूं :-) मैंने आपका लेख पढ़ा है, और मैं वास्तव में एमवीसी 4 में मजबूत टाइप किए गए मॉडल का उपयोग करता हूं ... लेकिन मेरे पास सरल चीज़ों के लिए व्यूबैग का उपयोग करने के खिलाफ कोई योग्यता नहीं है। अधिकांश लोग सी # से आ रहे हैं, और अन्य मजबूत टाइप की गई भाषाओं को उनकी विरासत के कारण गतिशीलता पर फहराया गया है (मैं भी एक 'मजबूत टाइप वाला' लड़का हूं)। लेकिन यह सब परीक्षण करने के लिए नीचे आता है! यदि आपके विचारों का परीक्षण किया जाता है तो गतिशील चर कोई फर्क नहीं पड़ता। वास्तव में हर जगह व्यूबैग का उपयोग करना और शुद्धता सुनिश्चित करने के लिए मजबूत प्रकारों पर भरोसा करने से काफी अधिक परीक्षण करना बेहतर होता है। अच्छा परीक्षण गतिशीलता बनाम मजबूत प्रकार के म्यूट की पसंद करते हैं। – Loudenvier

+0

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

+0

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

4

व्यूबैग का उपयोग करने के बजाय, व्यूडेटा का उपयोग करें ताकि आप जिस आइटम को स्टोर कर रहे हैं उसकी जांच कर सकें। ViewData ऑब्जेक्ट का उपयोग ऑब्जेक्ट्स के शब्दकोश के रूप में किया जाता है जिसे आप कुंजी द्वारा संदर्भित कर सकते हैं, यह व्यूबैग के रूप में गतिशील नहीं है।

// Set the [ViewData][1] in the controller 
ViewData["hideSearchForm"] = true;  

// Use the condition in the view 
if(Convert.ToBoolean(ViewData["hideSearchForm"]) 
    hideSearchForm(); 
+0

कैसे? हमें कम से कम एक उदाहरण दें;)। –

+0

यहां एक छोटा नमूना है – JustEngland

+1

फिर भी व्यूबैग व्यूडाटा से अधिक सुरुचिपूर्ण लगता है। मुझे स्ट्रिंग इंडेक्स पसंद नहीं है। – JustAMartin

98
@if (ViewBag.Error!=null) 
{ 
    // Injecting JavaScript here 
} 
+4

प्रिय @jazzcat, कृपया पहले अपना कोड जांचें, फिर इसे भेजें।अगर मैंने अपने नियंत्रक में 'ViewBag.Error' सेट नहीं किया है, जिसका अर्थ है कि व्यूबैग में रनटाइम पर' त्रुटि 'नामक कोई संपत्ति नहीं होगी, तो मुझे अपवाद मिलेगा। –

+20

@ सईदनेमाती, जैज़कैट के कोड ने मेरे लिए ठीक काम किया। व्यूबैग के लिए, कोई भी आइटम नहीं मिला शून्य होगा। याद रखें कि अंततः गतिशील के पीछे कुछ वास्तविक कोड है। व्यूबैग एक डायनामिक व्यूडेटा डिक्शनरी है, जो स्पष्ट रूप से त्रुटि को फेंकने के बजाय गैर-मौजूदा "गुणों" के लिए शून्य वापस करने का निर्णय लेता है। – devrelm

+1

यूप, devrelm सही है, मेरे लिए भी काम करता है ... – user1068352

2

आप ViewData.ContainsKey("yourkey") उपयोग कर सकते हैं।

नियंत्रक में:

ViewBag.IsExist = true; 

ध्यान में रखते हुए:

if(ViewData.ContainsKey("IsExist")) {...} 
+0

कृपया उचित होने पर कोड टैग का उपयोग करें। – matiasg

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