2009-09-15 8 views
7

मेरे पास एक कस्टम व्यूमोडेल है जो एक जेसनरसल्ट का उपयोग करके क्रमबद्ध है। व्यूमोडेल में कुछ गुण हैं जिन्हें सार्वजनिक होना है, लेकिन साथ ही इन गुणों को परिणामी जेसन आउटपुट में दिखाई नहीं देना चाहिए।मैं कुछ सार्वजनिक गुणों को जेसनरसेट में क्रमबद्ध करने से कैसे बाहर कर सकता हूं?

मैंने पहले से ही [NonSerialized] विशेषता का उपयोग करने का प्रयास किया है, लेकिन ऐसा कोई प्रभाव नहीं प्रतीत होता है।

क्या ऐसा करने का कोई आसान तरीका है? या मुझे अपना खुद का परिणाम टाइप करना होगा (जिस स्थिति में मैं शायद परेशान नहीं होगा)?

+0

अधिकतर उत्तर विशेषता का उपयोग कर रहे हैं या जो भी हो। मैं सिर्फ serializing के दौरान कुछ सार्वजनिक संपत्तियों को बाहर करना चाहता हूँ। मैं JSON.NET की तलाश में हूं जैसा कि @ चार्लीनो द्वारा सुझाया गया है लेकिन उसे रास्ता नहीं मिला। यह मामला है: मेरे पास 'त्रुटि' संपत्ति है जो त्रुटि तब होती है जब त्रुटि उत्पन्न होती है। क्लाइंट साइड संदेश दिखाने के लिए पहले इस के लिए जांच करेगा अन्यथा मॉडल की बाकी संपत्ति प्रदर्शित करेगा। जब कोई त्रुटि नहीं होती है, तो यह '{...," त्रुटि ": null}' प्रस्तुत करेगी! – CallMeLaNN

उत्तर

24

आप उन सदस्यों पर [ScriptIgnore] विशेषता डाल सकते हैं जिन्हें क्रमबद्ध नहीं किया जाना चाहिए। उदाहरण के लिए ScriptIgnoreAttribute Class in MSDN देखें।

+8

वहां अन्य लोगों के लिए विशेषता का पूरा नामस्थान [System.Web.Script.Serialization.ScriptIgnore] – EBarr

+0

नियमित एमवीसी 'रिटर्न जेसन()' --- फिर 'जेसन इग्नोर' का उपयोग करते समय 'स्क्रिप्ट इग्नोर' जैसा लगता है, 'Json.NET' – mmcrae

0

नहीं वास्तव में इस सवाल का जवाब आप के लिए देख रहे हैं, लेकिन आप निम्नलिखित कोड और अनाम वर्गों का उपयोग Json() धोखा कर सकते हैं:

MyModel model = ...; 
return Json(new MyModel {model.Prop1, model.Prop2}); 
+0

मुझे पता है कि मैं इसके बजाय अनाम प्रकारों का उपयोग कर सकता हूं। लेकिन इससे यूनिट परीक्षण परिणाम को अधिक कठिन बनाता है। इसका मतलब है कि मुझे या तो धारावाहिक परिणाम का विश्लेषण करना होगा या प्रतिबिंब का उपयोग करना होगा। –

+0

इकाई परीक्षण JsonResults के साथ शुरू करना मुश्किल है। आप इससे पहले कैसे कर रहे थे? ऐसा लगता है कि आप अंतर्निहित मॉडल को पुनर्प्राप्त नहीं कर सकते जो JsonResult को चलाता है। –

+1

यह कोई समस्या नहीं है। JsonResult.Data प्रॉपर्टी में ऑब्जेक्ट होता है जिसे क्रमबद्ध किया जाना है। चूंकि मैं किसी अज्ञात ऑब्जेक्ट प्रकार के बजाय एक कस्टम व्यूमोडेल का उपयोग कर रहा हूं, इसलिए मैं उस ऑब्जेक्ट को आसानी से पकड़ सकता हूं और इसकी गुणों का परीक्षण कर सकता हूं। –

0

आप एक आवरण वर्ग है कि केवल उन गुणों है कि आप में चाहते हैं को उजागर करता है बना सकते हैं JsonResult। नीचे दिए गए उदाहरण में, गाय के 2 गुण हैं - "लेग" और "म्यू"। मान लीजिए कि आप केवल संपत्ति के रूप में "लेग" का पर्दाफाश करना चाहते हैं। तब

मंद सीडब्ल्यू के रूप में CowWrapper = नई CowWrapper (ग)

एक आवरण वर्ग है कि केवल उजागर करता है "पैर" वापस आ जाएगी। यह DataGridView जैसी चीजों के लिए भी उपयोगी है यदि आप केवल गुणों का कुछ सबसेट प्रदर्शित करना चाहते हैं।

सार्वजनिक कक्षा गाय

लोक ReadOnly संपत्ति लेग() स्ट्रिंग के रूप में

get 

     return "leg" 

    end get 

अंत संपत्ति

लोक ReadOnly संपत्ति मू() स्ट्रिंग के रूप में

get 

     return "moo" 

    end get 

अंत संपत्ति

अंत वर्ग

सार्वजनिक कक्षा CowWrapper

Private m_cow as Cow = Nothing 

Public Sub New(ByVal cow as Cow) 

    m_cow = cow 

end Sub 


    m_cow = cow 

लोक ReadOnly संपत्ति लेग() स्ट्रिंग के रूप में

get 

     return m_cow.Leg() 

    end get 

अंत संपत्ति

अंत कक्षा

+0

यह काम करता है, लेकिन कुछ संपत्तियों की प्रतिलिपि बनाने की कीमत पर, इसलिए यह वास्तव में नहीं है कि मैं क्या देख रहा था। –

+0

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

+0

मुझे एहसास नहीं हुआ कि आप प्रतिबिंब के माध्यम से रनटाइम पर ऐसे प्रकार का निर्माण करना चाहते हैं। यह निश्चित रूप से बिना किसी अतिरिक्त कोडिंग के मेरे सभी कस्टम व्यूमोडेल प्रकारों को कवर करेगा। एक वैध दृष्टिकोण लेकिन तैयार किए गए टूल (अर्थात् जेसन) का उपयोग करने की तुलना में यह बहुत जटिल है।नेट) –

1

JavaScriptConverter वर्ग के लिए बढ़ाएँ प्रोपे शामिल नहीं है NonSerializedAttribute के साथ rties। फिर आप एक कस्टम ActionResult बना सकते हैं जो ऑब्जेक्ट को क्रमबद्ध करने के लिए आपके JavaScriptConverter का उपयोग करता है।

यह रैपर वर्ग उत्पन्न करने या अज्ञात वस्तुओं का उपयोग किए बिना (ठोस) उत्पन्न किए बिना ठोस और टेस्टेबल क्लास बनाता है।

+0

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

2

जेम्स न्यूटन-किंग से JSON.NET पर एक नज़र डालें। यह वही करेगा जो आप खोज रहे हैं।

+0

बिल्कुल सही! जैसा कि यह पता चला है, जेम्स ने एक मिलान जेसनरसेट प्रकार भी लिखा है: http://james.newtonking.com/archive/2008/10/16/asp-net-mvc-and-json-net.aspx –

2

बस कक्षा के बजाय वापस आने के लिए एक इंटरफ़ेस बनाएं।

public interface IMyViewModel { 
    string MyPublicProperty { get; set; } 
} 

फिर, इंटरफ़ेस, नहीं वर्ग एक वर्ग है कि इंटरफ़ेस विरासत

public class MyViewModel : IMyViewModel { 
    public string MyPublicProperty { get; set; } 
    public string MyNotSoPublicProperty { get; set; } 
} 

बना सकते हैं और वापस जाने के नियंत्रक कार्रवाई

public JsonResult MyJson(){ 
    IMyViewModel model = new MyViewModel(); 
    return Json(model); 
} 

में और जिसके परिणामस्वरूप JSON

हो जाएगा
{ 
    'MyPublicProperty': '' 
} 

क्लाइंट-साइड स्क्रिप्टिंग में चुनौतियों में से एक यह है कि यदि आप अपनी कक्षाएं बदल रहे हैं, तो आपको पता नहीं है कि आप क्लाइंट-साइड कार्यान्वयन को नष्ट कर रहे हैं या नहीं। यदि आप अपने JSON में इंटरफ़ेस प्रकारों का उपयोग करते हैं, तो आप समझते हैं कि यदि आप इंटरफ़ेस बदलते हैं, तो आप ऐसा कुछ कर रहे हैं जो संभावित रूप से क्लाइंट साइड कार्यान्वयन को मार रहा हो। और यह आपको क्लाइंट पक्ष को व्यर्थ में दोबारा जांचने से बचाता है यदि आप ऐसा कुछ बदल रहे हैं जो इंटीफेस में नहीं है (इस प्रकार क्रमबद्ध नहीं किया जा रहा है)।

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

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

+0

का उपयोग करते हुए आपके उत्तर के लिए धन्यवाद। यह एक बुरी विधि नहीं है, लेकिन यह सुनिश्चित करने के लिए एक और स्वचालित तरीका भी है कि आपके क्लाइंट-साइड क्लास सर्वर पक्ष के साथ सिंक हो रहे हैं: क्लाइंट साइड कोड के लिए टाइपस्क्रिप्ट का उपयोग करें और प्रोग्रामिक रूप से सर्वर साइड ऑब्जेक्ट्स से अपने क्लाइंट-साइड व्यूमोडेल जेनरेट करें संकलन के दौरान। अधिक जानकारी के लिए http://type.litesolutions.net/ देखें। –

+0

क्या यह दृष्टिकोण एक सूची serialized होने के साथ काम करेगा? मैं इसे काम नहीं कर सकता ... – tomasofen

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

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