2010-06-25 14 views
18

के लिए जेएसननेट को डिफ़ॉल्ट सीरिएलाइज़र के रूप में कैसे सेट करें, क्या सीरियललाइज/डीएसरियललाइज इकाइयों के दौरान डिफ़ॉल्ट WCF DataContractSerializer व्यवहार को ओवरराइड करना संभव है और इसके बजाय JSON.NET का उपयोग करना संभव है?डब्ल्यूसीएफ आरईएसटी सेवा

मेरे पास सिटी इकाई को संभालने के लिए निम्न सेवा अनुबंध है। डिज़ाइन कारणों से शहर इकाई में IsReference = true है, और इसलिए डिफ़ॉल्ट DataContractSerializer त्रुटियां बढ़ाता है।

"जीईटी" विधियों के लिए मैं जेसनकॉन्टर.डिसरियलइज ऑब्जेक्ट के साथ स्थिति को संभाल सकता हूं, लेकिन "पुट, पोस्ट, डिलीट" विधियों के साथ डेटाकंट्रैक्टसेरियलाइज़र को प्राथमिकता मिलती है और IsReference इकाइयों के लिए शिकायत करने में असफलता को क्रमबद्ध नहीं किया जा सकता है।

IOperationBehavior को लागू करने के लिए मुझे यह Post मिल गया है और अपना स्वयं का सीरियलाइज़र प्रदान करता है लेकिन मुझे नहीं पता कि इसके साथ जेसन.NET को कैसे एकीकृत किया जाए। और मेरा मानना ​​है कि इसके लिए और अधिक सीधा दृष्टिकोण होना चाहिए।

मैं इस परिदृश्य, या अन्य दृष्टिकोणों के बारे में सलाह के बारे में किसी भी मदद या मार्गदर्शन की सराहना करता हूं।

[ServiceContract] 
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed) 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 
public class CityService 
{ 
    [Description("Get all Cities")] 
    [WebGet(UriTemplate = "")] 
    public Message Cities() 
    { 

    } 

    [Description("Allows the details of a single City to be updated.")] 
    [WebInvoke(UriTemplate = "{code}", Method = "PUT")] 
    public Message UpdateCity(string code, City city) 
    { 
    } 
} 

बहुत धन्यवाद

Hossam

उत्तर

19

विस्तारक एनकोडर्स और सीरियललाइज़र का उपयोग (http://msdn.microsoft.com/en-us/library/ms733092.aspx देखें) या DataContractSerializerOperationBehavior के उपयोग जैसे डब्ल्यूसीएफ को विस्तारित करने के अन्य तरीकों को बहुत रोचक है, लेकिन आपकी विशेष समस्या के लिए आसान समाधान तरीके हैं।

आप पहले से ही परिणाम एक उपयोग वापस जाने के लिए Message प्रकार का उपयोग करते WCF4 आप निम्नलिखित की तरह कुछ कर सकते हैं:

public Message UpdateCity(string code, City city) 
{ 
    MyResponseDataClass message = CreateMyResponse(); 
    // use JSON.NET to serialize the response data 
    string myResponseBody = JsonConvert.Serialize(message); 
    return WebOperationContext.Current.CreateTextResponse (myResponseBody, 
       "application/json; charset=utf-8", 
       Encoding.UTF8); 
} 

त्रुटियों (जैसे HttpStatusCode.Unauthorized या HttpStatusCode.Conflict) के मामले में या अन्य स्थितियों में जब आप स्थापित करने की आवश्यकता एक HTTP स्थिति कोड (जैसे HttpStatusCode.Created) आप WebOperationContext.Current.OutgoingResponse.StatusCode का उपयोग करना जारी रख सकते हैं।

एक विकल्प के रूप में आप की भी वापसी हुई एक Stream (http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-web.aspx और http://msdn.microsoft.com/en-us/library/ms732038.aspx देखें) के बजाय Message माइक्रोसॉफ्ट JSON serializer से अतिरिक्त डिफ़ॉल्ट प्रसंस्करण के बिना किसी भी डेटा लौटाने के लिए कर सकते हैं। डब्ल्यूसीएफ 4 के मामले में आप CreateTextResponse के बजाय CreateStreamResponse (http://msdn.microsoft.com/en-us/library/dd782273.aspx देखें) का उपयोग कर सकते हैं। यदि आप इस तकनीक का उपयोग प्रतिक्रिया उत्पन्न करने के लिए करेंगे तो स्ट्रीम में लिखने के बाद 0 को स्ट्रीम स्थिति सेट करना न भूलें।

+0

ओलेग, बहुत धन्यवाद, यह स्ट्रीम प्रकार लौटकर एक आकर्षण की तरह काम करता है, यह माइक्रोस्कोफ्ट सीरियलाइज़र को रोकता है। मुझे डेटाकंट्रैक्टसाइरिएलाइज़र ऑपरेशनबिहियर के बारे में पता है, लेकिन यह मुझे XmlObjectSerializer से अपने स्वयं के सीरियलज़र को ले जाने के लिए ले जाता है जो एक आसान काम नहीं है। आपका प्रस्ताव बहुत आसान और सीधे आगे है, एक बार फिर धन्यवाद। – Hossam

+0

यह आने वाली सिटी ऑब्जेक्ट को deserializing कैसे संभालता है? –

+1

@ क्रिस्टोफर स्टॉट: उदाहरण के लिए देखें http://msdn.microsoft.com/en-us/library/ms734675.aspx "पठन संदेश" से शुरू होता है। – Oleg

1

वहाँ कुछ कारण है कि आप विशेष रूप से Json.NET पुस्तकालय का उपयोग करना चाहते है। यदि आप JSON वापस करना चाहते हैं, तो WebGet और WebInvoke विशेषताओं से केवल ResponseFormat प्रॉपर्टी का उपयोग क्यों न करें?

[WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)] 

अधिकांश मामलों के लिए यह होना चाहिए। डब्ल्यूसीएफ का कौन सा संस्करण आप चल रहे हैं? किसी भी कारण से आप वास्तविक प्रकार के बजाय संदेश प्रकार लौट रहे हैं?

+0

के अपने आपरेशन अनुबंध में यह WCF4 है। मेरे वेब मेंकॉन्फ़िगरेशन, मेरे में डिफ़ॉल्ट आउटपुट रीस्पॉन्सफॉर्मैट = "जेसन" है, इसलिए मुझे सेवा विधियों को सजाने की ज़रूरत नहीं है। डिज़ाइन करके मेरी सभी इकाइयों में [IsReference = true] है और डिफ़ॉल्ट डेटाकंट्रैक्टसेरियलाइज़र के साथ क्रमबद्ध नहीं किया जा सकता है। तो मुझे जेसननेट जैसे ऑनर सीरिएलाइज़र का उपयोग करना है जो [IsReference = true] के साथ इकाइयों को संभाल सकता है। मैं संदेश प्रतिक्रिया वापस कर रहा हूं ताकि मेरी प्रतिक्रिया दो बार serialzed न हो, एक बार json.net द्वारा और फिर DataContractSerializer द्वारा। यदि मैंने एक्ट्यूअल प्रकार वापस कर दिया है तो मुझे आपके जवाब के लिए "{\" शहर \ ": \" काहिरा \ "}" थैंक्स जैसे अमान्य जेसन मिलेगा। – Hossam

+0

तो यदि आप IsReference विशेषता का उपयोग नहीं करते हैं तो यह आपके लिए काम करता है लेकिन आपको किसी अन्य कारण से इसे डिज़ाइन द्वारा उपयोग करना होगा? –

+0

सही, IsReference एकमात्र मुद्दा है। यह कई पोस्टों में रिपोर्ट किया गया है DataContractJsonSerializer IsReference = true के साथ चिह्नित इकाइयों को क्रमबद्ध नहीं कर सकता है। यही कारण है कि मैं एक और Serializer का उपयोग करने के लिए देख रहा हूँ। बहुत धन्यवाद – Hossam

0

सेवा व्यवहार पर आपकी सेवा वेब config में यह निर्धारित करें:

<endpointBehaviors> 
    <behavior name="restfulBehavior"> 
     <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" /> 
     <!--<enableWebScript />--> 
    </behavior> 
</endpointBehaviors> 

या अपने इंटरफेस

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