2010-06-11 16 views
5

हमारे उत्पादन वातावरण में, हमारी डब्ल्यूसीएफ सेवाओं को XMLSerializer के साथ क्रमबद्ध किया जाता है। ऐसा करने के लिए हमारी सेवा इंटरफेस में [XMLSerializerFormat] विशेषता है। अब, हमें DataContractSerializer में बदलने की जरूरत है, लेकिन हमें अपने मौजूदा ग्राहकों के साथ संगत रहना चाहिए। इसलिए, हमें प्रत्येक सेवा को दोनों धारावाहिकों के साथ बेनकाब करना होगा।उसी होस्ट पर एक ही अनुबंध के लिए DataContractSerializer और XMLSerializer दोनों का समर्थन कैसे करें?

हम एक बाधा है: हम प्रत्येक अनुबंध इंटरफ़ेस दो बार फिर से परिभाषित नहीं करना चाहते, हम 50 सेवाओं अनुबंध इंटरफेस है और हम

IIncidentServiceXml 
IIncidentServiceDCS 
IEmployeeServiceXml 
IEmployeeServiceDCS 
IContractServiceXml 
IContractServiceDCS 

के लिए हम ऐसा कैसे कर सकते हैं नहीं करना चाहती?


अधिक जानकारी

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

हम कोड द्वारा सभी अंतिमबिंदुओं बनाने की कोशिश की हमारी अपनी सेवाहोस्ट फैक्ट्री कक्षा में। असल में हम प्रत्येक एंडपॉइंट को दो बार बनाते हैं। समस्या यह है कि रनटाइम पर, डब्ल्यूसीएफ शिकायत करता है कि सेवा के पास एक ही संपर्क नाम के साथ दो अंतराल हैं लेकिन विभिन्न अनुबंध डिस्क्रिप्शन उदाहरणों के साथ। संदेश कहता है कि हमें अलग-अलग अनुबंध नामों का उपयोग करना चाहिए या उसी अनुबंध डिस्क्रिप्शन इंस्टेंस का पुन: उपयोग करना चाहिए।

अन्य प्रयास:

हम भी प्रत्येक ContractDescription उदाहरण के लिए अलग नेमस्पेस का उपयोग करके इसे करने की कोशिश की। इस तरह हम एक ही अनुबंध इंटरफ़ेस रखना होगा (IIncidentService) लेकिन दो अलग अलग नामस्थान के साथ:

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: 
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.XmlSerializerOperationBehavior 
contract: http://ourcompany.cs/XML:IUserServiceWCF ----> System.NullReferenceException: Object reference not set to an instance of an object. 
    at System.ServiceModel.Description.XmlSerializerMessageContractExporter.ExportFaults(Object state) 
    at System.ServiceModel.Description.MessageContractExporter.ExportMessageContract() 
    at System.ServiceModel.Description.XmlSerializerOperationBehavior.System.ServiceModel.Description.IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext contractContext) 
    at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension) 

उत्तर

1

लघु:

http://ourcompany/XML/IIncidentService 
http://ourcompany/DCS/IIncidentService 
है कि हम आगे प्राप्त करने में सक्षम थे, लेकिन सेवा एक अजीब अपवाद के साथ दुर्घटनाग्रस्त हो गया साथ

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

This might be your only option

समस्या एक सेवा निर्दिष्ट करने के लिए वह यह है कि XmlSerializer उपयोग करने के लिए आप सेवा या अनुबंध पर [XmlSerializerFormat] विशेषता घोषित करने के लिए की जरूरत है। ठीक है हम एंडपॉइंट्स के लिए इसका उपयोग करना चाहते हैं, हम इसे वहां नहीं रख सकते हैं, इसलिए हमें अनुबंध पर रखने के साथ छोड़ दिया गया है। हालांकि, जब यह तक उबालता है, तो दोनों एंडपॉइंट समान सेवा का उपयोग कर रहे हैं और vicariously उसी अनुबंध सही हैं?

अच्छा, ऐसा नहीं होना चाहिए। आप अनुबंध प्राप्त कर सकते हैं ए अनुबंध बी से प्राप्त होता है, उसके बाद सेवा अनुबंध लागू करें ए दोनों अनुबंधों में सबकुछ सेवा के भाग है।इस उदाहरण के लिए हालांकि, अनुबंध बी हमारे मानक अनुबंध होगा, और अनुबंध ए एक इंटरफ़ेस होगा जो केवल [XmlSerializerFormat] विशेषता को परिभाषित करता है।

लेकिन मैं आपको वादा नहीं कर सकता कि परिवर्तन के बिना आपके मौजूदा क्लाइंट कोड के साथ काम करेगा।

+0

मैंने अपने प्रश्न को एक और प्रयास के साथ ऊपर अपडेट किया है – Sylvain

0

एक ही अनुबंध को लागू करने वाली दो सेवाओं के बारे में क्या?

तरह:

class DcsService : Service 
{} 

[XmlSerializerFormat] 
class XmlService : Service 
{} 

class Service : IServiceContract 
{} 

XmlSerializer के साथ कभी काम किया है, लेकिन हम अन्य प्रयोजनों के लिए इस संरचना का इस्तेमाल किया।

1

बस [डेटाकंट्रैक्ट] और [डेटामेम्बर] टैग का उपयोग करके अपना ऑब्जेक्ट बनाएं। XmlSerializer और DataContractSerializer दोनों ऑब्जेक्ट को ठीक से क्रमबद्ध करेंगे। उन्होंने डाटाकंट्रैक्ट सीरियलाइजेशन को संभालने के लिए 3.0 फ्रेमवर्क में एक्सएमएलएसरियललाइज़र को अपडेट किया। DataContractSerializer [Serializable] ऑब्जेक्ट्स को संभाल सकता है लेकिन व्यवहार सटीक नहीं है और कुछ tweaking लेता है।

डेटा अनुबंधों का उपयोग करके बस अपनी सभी वस्तुओं को बनाएं। इस तरह आपको दो कॉल करने (प्रत्येक के लिए एक) बनाने की चिंता करने की ज़रूरत नहीं है। आप XmlSerializer या DataContractSerializer का उपयोग बिना किसी समस्या के कर सकते हैं।

यदि आपको व्यवहार गुण जोड़ने की आवश्यकता है तो आप हमेशा [Serializable] और [DataContract] दोनों को जोड़ सकते हैं।

[Serializable] 
[DataContract] 
public class Customer 

{ 
    [DataMember] 
    public int Age { get; set; } 

    [DataMember] 
    public string Name { get; set; } 

    [DataMember] 
    public int Number { get; set; } 

    [DataMember] 
    public string FullName { get; set; } 

    [XmlIgnore] 
    public int IgnoredNumber { get; set; } 
} 

XmlSerializer को धारावाहिक के रूप में:

<?xml version="1.0" encoding="utf-16" ?> 
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Age>88</Age> 
    <Name>Bob</Name> 
    <Number>808</Number> 
    <FullName>Bob Jones</FullName> 
    </Customer> 

DataContractSerializer serializes के रूप में:

<?xml version="1.0" encoding="utf-8" ?> 
<Customer xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication1"> 
    <Age>88</Age> 
    <FullName>Bob Jones</FullName> 
    <Name>Bob</Name> 
    <Number>808</Number> 
    </Customer> 

आप स्पष्ट रूप से तो वे दोनों मैच वास्तव में नाम स्थान के लिए मजबूर कर सकते हैं। यह सिर्फ उदाहरण उद्देश्यों के लिए है।

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