2012-04-26 6 views
9

मैं एक WCFservice कि रिटर्न सामान्य शब्दकोश JSON करने के लिए धारावाहिक वस्तुओं का निर्माण करने की योजना बना रहा हूँ। दुर्भाग्य से, क्रमबद्धता विफल हो जाती है, क्योंकि ऑब्जेक्ट संभावित रूप से हमेशा अलग होता है। KnownTypes मदद कर सकते हैं नहीं है, क्योंकि संपत्ति प्रकार शब्दकोश है, और मैं KnownType नहीं कह सकता, के रूप में वर्ग संभावित हमेशा अलग हो जाएगा।मैं क्रमानुसार कर सकते शब्दकोश <स्ट्रिंग, वस्तु> DataContract serializer का उपयोग कर?

कोई भी विचार अगर यह 'अज्ञात प्रकार' क्रमानुसार करने संभव है?

मुझे अपने प्रत्येक वर्ग के लिए डेटाकंट्रैक्ट/डेटामेम्बर निर्दिष्ट करने की कोई बात नहीं है, लेकिन (कम से कम प्रोटोटाइप संस्करण के लिए) मैं प्रत्येक प्रतिक्रिया के लिए मजबूत प्रकार नहीं चाहता हूं। जावास्क्रिप्ट क्लाइंट सिर्फ परवाह नहीं करता है।

कैसे गुमनाम कक्षाओं के बारे में?

+0

मुझे पहले से ही इस तरह के लोगों को खुशी है। कृपया तर्कों के जवाब देने के लिए परेशान न हों कि डब्ल्यूसीएफ को इत्यादि के लिए कैसे नहीं बनाया गया था, आदि। यदि आप ज्ञात तरीके से हैं या यदि आप वहां हैं और वैध कारणों के लिए छोड़ दिया है तो क्या आप हमें बता सकते हैं कि क्या आप हमें बता सकते हैं (क्या कारणों?)। – tishma

उत्तर

7

नोट: यदि मैं मूल प्रश्न में उल्लिखित ज्ञात प्रकार की समस्या के समाधान के बारे में पढ़ना चाहता हूं, तो मैं अपने उत्तर की शुरुआत में बहुत सारे विवरण में गया हूं, अंत में कूदें उत्तर का

प्रदर्शन

benchmarks मैं भाग गया के आधार पर, JavaScriptSerializer दूर अन्य विकल्पों की तुलना में धीमी है और क्रमानुसार करने के रूप में लंबे 2x लेने कर सकते हैं/एक वस्तु DataContractSerializer की तुलना में deserialize।

ज्ञात प्रकार

कहा कि, JavascriptSerializer अधिक लचीला में है कि यह आप के नाम प्रकार 'समय से आगे निर्दिष्ट करने के लिए की आवश्यकता नहीं है, और धारावाहिक JSON में कम से कम क्लीनर है के लिए कोई ज़रूरत नहीं शब्दकोशों के मामले (उदाहरण देखें here)।

कि लचीलापन आसपास प्रकार के नाम से जाना जाता दूसरा पहलू यह है कि यह है कि एक ही JSON स्ट्रिंग वापस मूल प्रकार के deserialize करने में सक्षम नहीं होगा।

public class Person 
{ 
    public string Name { get; set; } 

    public int Age { get; set; } 
} 

और अगर मैं Dictinoary<string, object> का एक उदाहरण बना सकते हैं और यह serializing से पहले यह करने के लिए Person वर्ग का एक उदाहरण जोड़ें::

var dictionary = new Dictionary<string, object>(); 
dictionary.Add("me", new Person { Name = "Yan", Age = 30 }); 
var serializer = new new JavaScriptSerializer(); 
var json = serializer .Serialize(dictionary); 

मैं हूँ उदाहरण के लिए, मैं एक साधारण Person वर्ग है लगता है निम्नलिखित JSON {"me":{"Name":"Yan","Age":30}} प्राप्त करें जो कि बहुत साफ है लेकिन किसी भी प्रकार की जानकारी से रहित है। तो माना जाता है, तो आप एक ही सदस्य परिभाषा के साथ दो वर्गों है या यदि Person किसी भी अतिरिक्त सदस्यों को शुरू करने के बिना subclassed है:

public class Employee : Person 
{ 
} 

फिर वहाँ बस के लिए serializer गारंटी नहीं है कि JSON {"Name":"Yan","Age":30} deserialized किया जा सकता है सक्षम होने के लिए कोई रास्ता नहीं है सही प्रकार के लिए।

आप JavaScriptSerializer का उपयोग कर {"me":{"Name":"Yan","Age":30}} deserialize हैं, तो शब्दकोश में तुम वापस के साथ जुड़े मूल्य "मुझे" Person का एक उदाहरण लेकिन बजाय एक Dictionary<string, object>, एक सरल संपत्ति बैग नहीं है मिलता है।

आप एक Person उदाहरण वापस पाने के लिए चाहते हैं, आप (आप सबसे शायद करना चाहते हैं, हालांकि होगा कभी नहीं!) कर सकता है परिवर्तित कि Dictionary<string, object>ConvertToType सहायक विधि का उपयोग कर:

var clone = serializer.Deserialize<Dictionary<string, object>>(json); 
var personClone = serializer.ConverToType<Person>(clone["me"]); 

दूसरी ओर, यदि आप उन JSON को सही प्रकार में deserializing के बारे में चिंता करने की आवश्यकता नहीं है और JSON serailization एक प्रदर्शन बाधा नहीं है (अपना कोड प्रोफाइल करें और पता लगाएं कि सीरियलाइजेशन पर कितना सीपीयू समय बिताया गया है यदि आपने पहले से ऐसा नहीं किया है) तो मैं कहूंगा बस जावास्क्रिप्ट Serializer का उपयोग करें।

इंजेक्शन ज्ञात प्रकार

, अगर दिन के अंत में, आप अभी भी DataContractSerializer का उपयोग करें और उन KnownTypes इंजेक्षन करने की जरूरत की जरूरत है, यहाँ दो चीजें आप की कोशिश कर सकते हैं।

1) ज्ञात प्रकारों की सरणी को DataContractSerializer constructor पर पास करें।

2) DataContractSerializer के लिए आपकी रुचि का प्रकार) का पता लगाने का साधन के साथ DataContractResolver का एक उपवर्ग (दर्रा constructor

आप एक तरह के 'ज्ञात प्रकार रजिस्ट्री' है कि प्रकार का ट्रैक रखता है बना सकते हैं कि शब्दकोश में जोड़ा जा सकता है, और यदि आप सभी प्रकार है कि आप DataContractSerializer को इंजेक्षन करने की आवश्यकता होगी नियंत्रित करते हैं, आप सबसे सरल बात की कोशिश कर सकते हैं:

  1. एक प्रकार जोड़ने के लिए स्थिर तरीकों के साथ एक KnownTypeRegister कक्षा बनाएं ज्ञात प्रकारों की सूची में:

var serializer = new DataContractSerializer(typeof(Dictionary<string, object>), KnownTypeRegister.Get());: जब आप serializer निर्माण

[DataContract] 
public class Person 
{ 
    static Person() 
    { 
     KnownTypeRegister.Add(typeof(Person)); 
    } 
    [DataMember] 
    public string Name { get; set; } 
    [DataMember] 
    public int Age { get; set; } 
}
  • रजिस्टर से भी जाना जाता है प्रकार के सरणी प्राप्त करें:

    public static class KnownTypeRegister 
    { 
        private static readonly ConcurrentBag _knownTypes = new ConcurrentBag(); 
        public static void Add(Type type) 
        { 
         _knownTypes.Add(type); 
        } 
        public static IEnumerable Get() 
        { 
         return _knownTypes.ToArray(); 
        } 
    }
  • एक स्थिर निर्माता कि रजिस्टर के साथ प्रकार पंजीकृत करता जोड़े

    अधिक गतिशील/बेहतर विकल्प possibl हैं ई लेकिन वे कार्यान्वित करने के लिए और भी मुश्किल हैं, यदि आप गतिशील ज्ञात प्रकार के रिज़ॉल्यूशन के बारे में अधिक पढ़ना चाहते हैं, तो here विषय पर जुवाल लोवी के एमएसडीएन आलेख पर नज़र डालें। इसके अलावा, कार्लोस फिगुइरा द्वारा this blog post भी आगे बढ़ने के तरीके जैसे अधिक गतिशील तकनीकों पर विवरण में जाता है, जब आप इस विषय पर होते हैं तो पढ़ने के लायक होते हैं!

  • +0

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

    1

    अस्वीकरण मैं आपको डब्ल्यूसीएफ एंडपॉइंट पर object का पर्दाफाश करने की सलाह नहीं देता हूं; यह 'लचीला' दिखाई देता है यह एक अच्छा विचार नहीं है क्योंकि आपने यह निर्दिष्ट नहीं किया है कि आपकी सेवा द्वारा किस प्रकार की जानकारी दी जाएगी।

    और अब एक जवाब

    के लिए अपने WCF कॉल एक ajax कॉल से भस्म किया जा रहा है और आप इसे Javascript client just doesn't care. तो क्यों नहीं अपने WCF कॉल बस एक स्ट्रिंग लौटाने कर डाल के रूप में? फिर अपने WCF कॉल के आंतरिक JavaScriptSerializer

    public string MyServiceMethod() 
    { 
        var hash = new Dictionary<string, object>(); 
        hash.Add("key1", "val1"); 
        hash.Add("key2", new { Field1 = "field1", Field2 = 42}); 
        var serialized = new JavaScriptSerializer().Serialize(hash); 
        return serialized; 
    } 
    

    disclaimer2 का उपयोग कर यह (जब से तुम प्रश्न पूछा) समाप्त करने के लिए एक साधन है Dictionary<string, object> को क्रमानुसार कर सकते हैं - मैं एक अच्छी तरह से परिभाषित करना होगा एक उत्पादन गुणवत्ता आवेदन के लिए इंटरफ़ेस इसलिए यह स्पष्ट था कि अनुरोध किया जा रहा था और तार पर वापस भेजा गया था।

    +0

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

    +0

    हालांकि, जावास्क्रिप्ट कोड को बिल्कुल पता होना होगा कि प्रोटोटाइप से उत्पादन के लिए सभी तरह से अनुरोध से क्या लौटाया गया है, और मैं नहीं देख सकता कि .NET में सख्त टाइपिंग उसमें कैसे मदद कर सकती है। यह कर सकते हैं? – tishma

    +1

    tishma, मेरे पास कोई मेट्रिक्स नहीं है कि 'DataContract' तेज होगा या नहीं। हालांकि यह मुझे आश्चर्य नहीं करेगा अगर किसी तीसरे पक्ष JSON serializer (जैसे Json.NET) का उपयोग करके क्रमबद्ध करना और स्ट्रिंग लौटने से WCF को क्रमबद्ध करने के लिए तेज़ हो सकता है। और नहीं, सख्त टाइपिंग चीजों के जावास्क्रिप्ट पक्ष में मदद नहीं करेगी लेकिन सख्त टाइपिंग के साथ आप अपने 'सार्वजनिक एपीआई' को देख सकते हैं और 'डिक्शनरी <स्ट्रिंग, ऑब्जेक्ट>' को उजागर करने के विरोध में आप जो एक्सपोज़ करते हैं, उसे देखते हैं। क्या जानता है – wal

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

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