2010-01-06 16 views
8

को कैसे दूर किया जाए हमने देखा है कि जब हम एक डब्ल्यूसीएफ सेवा का पर्दाफाश करते हैं जो विभिन्न एक्सएमएल सीरियलाइजेशन विशेषताओं से सजाए गए वर्गों का उपयोग करता है, इस तथ्य के बावजूद कि हम इंटरफ़ेस पर XmlSerializerFormat विशेषता का उपयोग करते हैं किसी भी ऑपरेशन के पैरामीटर पर किसी भी XmlRoot विशेषता पूरी तरह से अनदेखा हो जाती है। पैरामीटर का नामस्थान हमेशा सेवा का होता है और जो हम निर्दिष्ट नहीं करते हैं।डब्लूसीएफ में XmlRoot विशेषता को अनदेखा क्यों किया जाता है और इस

यह हमें समस्याएं पैदा कर रहा है क्योंकि यह एएसएमएक्स के साथ पिछड़ा संगत नहीं लगता है और यह भी कि हम बिज़टॉक का उपयोग कर रहे हैं, और एक्सएमएल के आदान-प्रदान के आकार पर कड़े नियंत्रण की आवश्यकता है।

कुछ सवाल तो -

  1. किसी को जानता है क्या औचित्य इस निर्णय के पीछे है?
  2. कोई भी जानता है कि यह कैसे हो रहा है? मैं छापों कि WCF, XmlSerializerFormat विशेषता के साथ, XmlSerialiser का उपयोग करता प्रकार serialise करने के लिए है, जो XmlRoot सुझाव है कि ध्यान में रखा जाना चाहिए, के तहत किया गया है कि कैसे आ यह स्थिति नहीं है? (यह, केवल तथ्य यह है कि के कारण है सोप लिफाफा ध्यान में रखते हुए, पैरामीटर जड़ है नहीं?)
  3. अधिकांश महत्वपूर्ण बात - किसी को भी जानता है वहाँ एक रास्ता 'मुद्दा मजबूर' के लिए है - यानी हमारे चयन के नामस्थान के पैरामीटर प्राप्त करें?

मैं this पोस्ट देखा है, लेकिन मैं नहीं मानता कि यह मेरे सवाल के लिए प्रासंगिक है -

वैगनर Silveira के अनुरोध के अनुसार -

[ServiceContract(Namespace = "http://servicecontract"), 
XmlSerializerFormat(Style = OperationFormatStyle.Document)] 
public interface ITestService 
{ 
    [OperationContract] 
    MyOtherType MyTestMethod(MyType obj); 
} 

// Composite class for DCS and XMLS 
[Serializable, XmlType, XmlRoot(Namespace = "http://datacontract")] 
public class MyType 
{ 
    [XmlAttribute] 
    public string StringValue { get; set; } 
} 

// Composite class for DCS and XMLS 
[Serializable, XmlType, XmlRoot(Namespace = "http://datacontract")] 
public class MyOtherType 
{ 
    [XmlAttribute] 
    public string OtherStringValue { get; set; } 
} 
- ठेके मैं इस्तेमाल किया यह परीक्षण करने के लिए कर रहे हैं

उत्तर

2

मुझे लगता है कि आप संदेश प्रारूप के रूप में SOAP का उपयोग कर रहे हैं। इस मामले में, जिस ऑब्जेक्ट को आप क्रमबद्ध कर रहे हैं वह एक्सएमएल की जड़ नहीं है, साबुन लिफाफा है। तो यह समझ में आता है कि XmlRoot को अनदेखा कर दिया जाएगा। डिफ़ॉल्ट रूप से डब्ल्यूसीएफ आपके लिए एक संदेश अनुबंध बनाएगा और प्रतिक्रिया का नाम देगा और इसमें सेवा का नामस्थान होगा। SOAP पर पूर्ण नियंत्रण रखने के लिए आप क्या कर सकते हैं create your own message contract

निम्नलिखित दो वर्गों बनाएँ:

[MessageContract] 
public class MyTestMethodRequest 
{ 
    [MessageBodyMember(Namespace = "http://datacontract")] 
    public MyType MyType; 
} 

[MessageContract] 
public class MyTestMethodResponse 
{ 
    [MessageBodyMember(Namespace = "http://datacontract")] 
    public MyOtherType MyOtherType; 
} 

उसके बाद निम्न के लिए आपकी सेवा संचालन के हस्ताक्षर बदल जाते हैं।

अनुरोध

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Header> 
    <Action xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none" 
      s:mustUnderstand="1">http://servicecontract/TestService/MyTestMethod</Action> 
    </s:Header> 
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <MyTestMethodRequest xmlns="http://servicecontract"> 
     <MyType StringValue="foo" xmlns="http://datacontract" /> 
    </MyTestMethodRequest> 
    </s:Body> 
</s:Envelope> 

रिस्पांस

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Header /> 
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <MyTestMethodResponse xmlns="http://servicecontract"> 
     <MyOtherType OtherStringValue="bar" xmlns="http://datacontract" /> 
    </MyTestMethodResponse> 
    </s:Body> 
</s:Envelope> 
+1

धन्यवाद जॉन हमने संदेशकंट्रैक्ट विकल्प का पता लगाया है, यह सिर्फ कुछ ऐसा लगता है जो एएसएमएक्स में काम करता है, यही कारण है कि मैं रूट नोड तर्क के बारे में निश्चित नहीं था, लेकिन मुझे लगता है कि यह समझ में आता है। व्यक्तिगत रूप से मुझे लगता है कि पिछड़ा संगतता के लिए काफी झटका है। –

1

मुझे नहीं पता कि क्यों डब्ल्यूसीएफ XmlRoot को अनदेखा करता है, इसलिए मैं आपके प्रश्न के उस हिस्से का जवाब नहीं दे सकता। लेकिन मेरे पास समस्या को हल करने के कुछ तरीके हैं।

  1. पहले डब्लूएसडीएल के साथ शुरू होता है।
    यदि आपके पास एक्सएमएल नेमस्पेस का एक विशेष सेट है, तो आप उन संदेशों पर आवेदन करना चाहते हैं जो भेजे जाते हैं और प्राप्त किए जाते हैं, उन्हें स्पष्ट रूप से निर्दिष्ट करने के लिए डब्लूएसडीएल और एक्सएमएल स्कीमा का उपयोग करें।

    फिर, सर्वर-साइड स्टब कोड, या क्लाइंट-साइड प्रॉक्सी कोड जेनरेट करें, सीधे उस डब्लूएसडीएल से the svcutil.exe tool के माध्यम से।

  2. use a custom ServiceHost
    आप के लिए खुला अन्य विकल्प, this link में वर्णित है, कि XmlRoot उपेक्षा या XmlType संदेश प्रकारों पर विशेषताओं के लिए WCF के फैसले को ओवरराइड करता है एक कस्टम ServiceHost उपयोग करने के लिए है।


आप डबल्यूएसडीएल-पहले दृष्टिकोण के लिए जाने के लिए चुनते हैं, तो डबल्यूएसडीएल इस तरह दिखना चाहिए:

<?xml version="1.0" encoding="utf-8" ?> 

<definitions 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    targetNamespace="urn:The-Service-namespace" 
    xmlns:tns="urn:The-Service-namespace" 
    xmlns:s="http://www.w3.org/2001/XMLSchema" 
    xmlns:n0="urn:The-Request-namespace" 
    xmlns:n1="urn:The-Response-namespace" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    elementFormDefault= "unqualified" 
    > 

    <types> 
     <s:schema targetNamespace="urn:The-Request-namespace" > 
     <s:complexType name="Type1"> 
      <s:sequence> 
      <s:element name="x" minOccurs="1" maxOccurs="1" type="s:string"/> 
      </s:sequence> 
     </s:complexType> 
     <s:element name="Type1" type="n0:Type1" /> 
     </s:schema> 


     <s:schema targetNamespace="urn:The-Response-namespace" > 
     <s:complexType name="Type2"> 
      <s:sequence> 
      <s:element name="x" minOccurs="1" maxOccurs="1" nillable="false" type="s:string"/> 
      <s:element name="y" minOccurs="1" maxOccurs="1" nillable="false" type="s:int"/> 
      <s:element name="z" minOccurs="1" maxOccurs="1" nillable="false" type="s:boolean" /> 
      </s:sequence> 
     </s:complexType> 
     <s:element name="Type2" type="n1:Type2" /> 
     </s:schema> 

    </types> 



<message name="RequestMessage"> 
    <part name="inPart1" element="n0:Type1" /> 
</message> 
<message name="ResponseMessage"> 
    <part name="outPart1" element="n1:Type2" /> 
</message> 



<portType name="PortTypeName"> 
    <operation name="Method1"> 
     <input message="tns:RequestMessage" /> 
     <output message="tns:ResponseMessage" /> 
    </operation> 
</portType> 



<binding name="InterfaceName" type="tns:PortTypeName"> 
    <soap:binding 
     transport="http://schemas.xmlsoap.org/soap/http" 
     style="rpc" /> 

    <operation name="Method1"> 
     <soap:operation soapAction="" style="document" /> 
     <input> <soap:body use="literal" /> </input> 
     <output> <soap:body use="literal" /> </output> 
    </operation> 
</binding> 

</definitions> 

यह डबल्यूएसडीएल बहुत सरल है - यह एक एकल आपरेशन को परिभाषित करता है , एक अनुरोध संदेश और एक प्रतिक्रिया संदेश के साथ।

सूचना वहाँ तीन नामस्पेस हैं:

  • कलश:-सेवा-नाम स्थान
    तत्व यह है कि अनुरोध और प्रतिक्रिया लपेटता के लिए इस्तेमाल किया - < सोप के अंदर पहला तत्व: शरीर >
  • urn: अनुरोध-नामस्थान
    उस अनुरोध रैपर के अंदर लिपटे तत्व के लिए उपयोग किया जाता है, जो टाइप 1 के उदाहरण में deserialized हो जाता है।
  • urn: द-रेस्पॉन्स-नेमस्पेस
    उस प्रतिक्रिया रैपर के अंदर लिपटे तत्व के लिए उपयोग किया जाता है, जो टाइप 2 के उदाहरण में deserialized हो जाता है।

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

+0

धन्यवाद Cheeso:

[OperationContract] public MyTestMethodResponse MyTestMethod(MyTestMethodRequest request) { return new MyTestMethodResponse { MyOtherType = new MyOtherType { OtherStringValue = "bar" } }; } 

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

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