2016-01-06 11 views
20

मैं बहुत तरह TempData का उपयोग करके एक रीडायरेक्ट के बाद एक कार्रवाई को डेटा पास करने की कोशिश कर रहा है:स्टोर जटिल वस्तु

if (!ModelState.IsValid) 
{ 
    TempData["ErrorMessages"] = ModelState; 
    return RedirectToAction("Product", "ProductDetails", new { code = model.ProductCode }); 
} 

लेकिन दुर्भाग्य से यह निम्न संदेश के साथ असफल रहने के है:

'System.InvalidOperationException The Microsoft.AspNet.Mvc.SessionStateTempDataProvider' cannot serialize an object of type 'ModelStateDictionary' to session state.'

मुझे the MVC project in Github में कोई समस्या मिली है, लेकिन यह बताती है कि मुझे यह त्रुटि क्यों मिल रही है, मैं नहीं देख सकता कि एक व्यवहार्य विकल्प क्या होगा।

एक विकल्प ऑब्जेक्ट को जेसन स्ट्रिंग में क्रमबद्ध करना होगा और फिर इसे वापस बेकार करना होगा और ModelState का पुनर्निर्माण करना होगा। क्या यह सबसे अच्छा तरीका है? क्या मुझे कोई संभावित प्रदर्शन समस्याएं ध्यान में रखना आवश्यक है?

और आखिरकार, या तो जटिल वस्तु को क्रमबद्ध करने या किसी अन्य पैटर्न का उपयोग करने के लिए कोई विकल्प हैं जिसमें TempData का उपयोग शामिल नहीं है?

+0

यदि आप ऐसा करने नहीं दिया जाना चाहिए। यदि मॉडलस्टेट मान्य नहीं है तो डिफ़ॉल्ट व्यवहार केवल अमान्य मॉडल के साथ एक ही दृश्य को वापस करने के लिए है। तो आपको केवल यह रिटर्न व्यू (मॉडल) करना चाहिए; और कार्रवाई – hjgraca

+0

पर रीडायरेक्ट नहीं किया गया यह केवल एक उदाहरण है, मैं TempData में किसी भी जटिल ऑब्जेक्ट को स्टोर करने का कोई तरीका ढूंढ रहा हूं, जरूरी मॉडलस्टेट नहीं। साथ ही, ऐसे परिदृश्य हो सकते हैं जहां आप अपनी सलाह का पालन नहीं कर सकते हैं, जो मैं मानता हूं कि सबसे अच्छा अभ्यास – elolos

+1

@hjgraca इस प्रकार की स्थिति के लिए उपयोग केस एक दृश्य है जिसमें डेटा की सूची जोड़ने और संपादित करने के लिए कई आंशिक विचार हैं। उदाहरण के लिए, दृश्य के लिए मॉडल वास्तव में मॉडलों की एक सूची है, फिर एक इनलाइन ऐड फॉर्म है जिसमें इसका अपना मॉडल है (जिनकी त्रुटियों को वापस भेजने की आवश्यकता है) और फिर प्रत्येक आइटम को इनलाइन भी संपादित किया जाता है (प्रत्येक में अपनी त्रुटियां होती हैं)। यह आसानी से क्लाइंट-साइड फ्रेमवर्क जैसे अंगुलर के साथ किया जाता है, लेकिन रेजर के साथ इतना आसान नहीं है। –

उत्तर

38

आप इस तरह विस्तार तरीकों बना सकते हैं:

public static class TempDataExtensions 
{ 
    public static void Put<T>(this ITempDataDictionary tempData, string key, T value) where T : class 
    { 
     tempData[key] = JsonConvert.SerializeObject(value); 
    } 

    public static T Get<T>(this ITempDataDictionary tempData, string key) where T : class 
    { 
     object o; 
     tempData.TryGetValue(key, out o); 
     return o == null ? null : JsonConvert.DeserializeObject<T>((string)o); 
    } 
} 

और, इस प्रकार आप उन्हें प्रयोग कर सकते हैं:

कहो objectA प्रकार ClassA की है।

TempData.Put("key", objectA);

और इसे पुनः प्राप्त करने आप यह कर सकते हैं:: आप इस तरह ऊपर उल्लेख विस्तार विधि का उपयोग कर अस्थायी डेटा शब्दकोश को यह जोड़ सकते हैं

var value = TempData.Get<ClassA>("key") जहां value लिया गया प्रकार ClassA का हो जाएगा

+0

अच्छा एक! एक जादू की तरह काम करता है – Danilow

0

मैं टिप्पणी नहीं कर सकता लेकिन मैंने एक पीईके भी जोड़ा जो जांचने के लिए अच्छा है कि अगले जीईटी के लिए वहां पढ़ा या पढ़ा जाए या नहीं।

public static T Peek<T>(this ITempDataDictionary tempData, string key) where T : class 
{ 
    object o = tempData.Peek(key); 
    return o == null ? null : JsonConvert.DeserializeObject<T>((string)o); 
} 

उदाहरण

var value = TempData.Peek<ClassA>("key") where value retrieved will be of type ClassA 
संबंधित मुद्दे