2010-02-21 16 views
20

पर गुमनाम प्रकार का एक उदाहरण पास करना मेरे पास एक डब्ल्यूसीएफ सेवा विधि है जो किसी ऑब्जेक्ट की अपेक्षा करती है और उसके बाद प्रतिबिंब का उपयोग करके अपनी गुणों को पुनर्प्राप्त करती है।डब्ल्यूसीएफ

ग्राहक पक्ष पर मैं एक गुमनाम प्रकार वस्तु

var obj = new {FirstName="John", LastName="Doe"} 

बना सकते हैं और यह विधि के लिए गुजरती हैं।

Type '<>f__AnonymousType0`2[System.String,System.String]' cannot be serialized. 
Consider marking it with the DataContractAttribute attribute, and marking all 
of its members you want serialized with the DataMemberAttribute attribute. 
See the Microsoft .NET Framework documentation for other supported types. 

मैं क्रमबद्धता विशेषताओं के साथ वास्तव में कोई प्रकार है और न ही गुण स्पष्ट रूप से घोषित न होने के कारण प्रकार या उसके सदस्यों चिह्नित नहीं कर सकते: मैं एक अपवाद हो रही है। क्या उस समस्या को दूर करने का कोई तरीका है?

उत्तर

17

ऐसा मत करो।

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

आपको ऐसा कुछ लिखने में 5 मिनट लगेंगे जो इसे अच्छे से संभाल सकता है। इस तरह की किसी भी तकनीक का उपयोग करने से आपको सड़क के नीचे कुछ भविष्य के बिंदु पर डिबगिंग के घंटे लगेंगे।

+0

हाँ, मैं कुंजी-ऑब्जेक्ट्स – Andrey

+0

का एक शब्दकोश पास कर चुका हूं, मेरे पास एक ही समस्या थी और मुझे पता चला कि यह एक बुरा विचार था। मेरा बेहतरीन घंटा नहीं। मैं सिर्फ क्यूरू को भविष्यवाणी के बारे में बताता था कि उसने क्या भविष्यवाणी की थी। – Four

1

आपको पहले से ही जवाब मिल गया है। यह नहीं किया जा सकता है।

वास्तव में, आप एक विधि से किसी अज्ञात प्रकार का उदाहरण अपने प्रोग्राम में पास नहीं कर सकते हैं। आप निश्चित रूप से प्रोग्राम के बीच उन्हें पास नहीं कर सकते हैं।

+0

असल में, आप कर सकते हैं - आप "ऑब्जेक्ट" के रिटर्न प्रकार को परिभाषित कर सकते हैं और फिर केवल अनाम प्रकार का अपना उदाहरण वापस कर सकते हैं। यह एक अनाम प्रकार है, लेकिन यह अभी भी अंततः "ऑब्जेक्ट" से निकलता है। अनुशंसित नहीं है, न ही इरादा - लेकिन यह संभव है - कम से कम .NET –

+0

@marc_s: यह संकलित होगा लेकिन काफी बेकार होगा, क्योंकि 'System.Object' के रिटर्न प्रकार के लिए कोई मेटाडेटा नहीं बनाया जाएगा। – Aaronaught

+0

@Aaronaught: मैंने कभी नहीं कहा कि यह किसी भी तरह से, आकार या रूप में उपयोगी था - बस संभव :-) मैं इसे कभी नहीं करूँगा, लेकिन यह तकनीकी रूप से संभव है –

2

नहीं, ऐसा नहीं है। हालांकि एक विधि से गुमनाम प्रकार की वस्तुओं को वापस करने के लिए चाल और तकनीकें हैं, तो आप उन्हें डब्ल्यूसीएफ पर नहीं भेज सकते हैं।

डब्ल्यूसीएफ को अपने सभी ठोस प्रकारों को जानने की आवश्यकता है जो पूरे भेजे जाएंगे, क्योंकि आप वास्तव में केवल .NET विधि को कॉल नहीं कर रहे हैं। इसके बजाए, संदेश कॉल को क्रमबद्ध संदेश में परिवर्तित कर दिया जाता है, और इसलिए, किसी भी "चीज" को डब्ल्यूसीएफ कॉल पर पारित किया जाना चाहिए क्रमिक होना चाहिए - कोई अपवाद नहीं।

19

answers suggesting कि आप can't use an anonymous type over WCF गलत हैं।

यदि आप चैनल पर अपने प्रकारों को क्रमबद्ध करने के लिए डिफ़ॉल्ट DataContractSerializer का उपयोग कर रहे हैं, तो हाँ, उत्तर सही हैं। इसका कारण यह है DataContractSerializer निम्न परिदृश्यों का समर्थन करता है: का उपयोग कर धारावाहिक XML Serialization

  • प्रकार क्रमशः DataContract attribute
  • Plain-Old-C#-Object (POCO) Serialization
  • का उपयोग कर धारावाहिक

    1. प्रकार Serializable attribute
    2. प्रकार का उपयोग कर धारावाहिक, वे विफल निम्नलिखित कारणों से अनाम प्रकारों के साथ:

      1. आप अज्ञात प्रकारों पर विशेषताओं को लागू नहीं कर सकते हैं।
      2. एक्सएमएल सीरियलाइजेशन के लिए एक डिफ़ॉल्ट पैरामीटर रहित कन्स्ट्रक्टर की आवश्यकता होती है, जो गुमनाम प्रकारों के पास नहीं है।
      3. एक ही रूप में 1.
      4. एक ही रूप में 2.

      हालांकि, आप DataContractSerializer उपयोग करने के लिए WCF में अपने संदेश को क्रमानुसार करने के लिए मजबूर नहीं कर रहे हैं। आप custom message formatter बना सकते हैं जिसका उपयोग आप क्रमबद्ध करने के लिए स्वयं कर सकते हैं।

      यदि आप अनुरोधों के परिणाम के रूप में भेज रहे प्रकारों को अज्ञात प्रकार हैं तो आपको कोई समस्या है। जब आप परिणाम वापस प्राप्त करेंगे, तो यह नामस्थान के भीतर एक निश्चित नाम होगा (.NET अर्थ में नहीं, लेकिन एक एसओए अर्थ में) और आपको उस ठोस प्रकार के मैपिंग को अनाम प्रकार पर वापस संभालना होगा । हालांकि, क्योंकि आपके पास वास्तविक अज्ञात प्रकार या कोड में इसे कम करने के तरीकों तक पहुंच नहीं है (कम से कम एक गतिशील तरीके से), आपके पास किसी ऑब्जेक्ट के साथ पास करने के अलावा कोई विकल्प नहीं है, अगर यह आपको वापस भेज दिया गया है, यह इस तरह के बेकार बनाता है, क्योंकि हर किसी को गतिशील जैसे बुरे प्रथाओं का उपयोग करना होगा (स्वयं में एक बुरा अभ्यास नहीं, बल्कि इस मामले में इन सीमाओं को पाने के लिए, हाँ), या cast-by-example

      तो अंत में मैं कहना है कि यह निश्चित रूप से है, जबकि संभव गुमनाम प्रकार क्रमानुसार और उन्हें तार पर भेजने के लिए, काम invovled आमतौर पर इसके लायक नहीं है।

    +2

    +1। -1 एक ऐसी तकनीक का जिक्र करने के लिए जो शुद्ध बुराई है। मुझे चिंता है कि कोई इसे पढ़ेगा और "बुरी प्रथाओं" चेतावनी को अनदेखा करेगा - रिफैक्टरिंग भूल जाओ, आपको एक एक्सोसिस्ट की आवश्यकता होगी। – Aaronaught

    +5

    किसी भी तकनीक का उल्लेख ज्ञान के साझाकरण पर विचार किया जाना चाहिए और नाराज नहीं होना चाहिए। इसके अलावा, यहां तक ​​कि exorcists राक्षसों के बारे में जानने की जरूरत है। –

    0

    जैसा कि पहले कहा गया था, वस्तुओं को deserializable होना चाहिए और इसलिए आपको संरचना को पहले से परिभाषित करना होगा। हालांकि, आप उन्हें परिभाषित करने के लिए विरासत का उपयोग कर सकते हैं, और इसलिए दर्द कम करें। डब्ल्यूसीएफ ज्ञात टाइप विशेषता प्रदान करता है ताकि सेवा संचालन को बेस क्लास का ऑब्जेक्ट प्राप्त हो सके और इसे व्युत्पन्न कक्षा के किसी ऑब्जेक्ट में deserialize किया जा सके। तो आपके पास अभी भी केवल एक (या कुछ) सेवा संचालन होगा जो आपके सभी परिदृश्यों को संभाल सकता है।

    4

    आप JSON स्ट्रिंग में वस्तु को क्रमानुसार और WCF के माध्यम से भेजने के लिए, तो तरह हो सकता है:

    //in WCF Server 
    dynamic mysentclass = new { FirstName = "John", LastName = "Doe" }; 
    string jsonstring = JsonConvert.SerializeObject(mysentclass, Newtonsoft.Json.Formatting.Indented); 
    //send the string through WCF 
    
    //in WCF client 
    dynamic myreceivedclass = JsonConvert.DeserializeObject<dynamic>(jsonstring); 
    MessageBox.Show(myreceivedclass.FirstName.ToString() + " " + myreceivedclass.LastName.ToString()); 
    

    उदाहरण Json.Net है, जो यहाँ प्राप्त किया जा सकता का उपयोग करता है:

    http://www.nuget.org/packages/Newtonsoft.Json/

    आप System.Web.Script.Serialization.JavaScriptSerializer (System.Web.Extensions.dll में) का भी उपयोग कर सकते हैं, जो Json.Net जितना शक्तिशाली नहीं है, लेकिन सरल वस्तुओं के लिए पर्याप्त होगा।