2011-07-11 2 views
2

サードパーティのwsdlに基づくサービスの実装に問題があります。サードパーティが私のサービスに呼び出すと、トレース内のデータを見ることができますが、サービスのパラメータはデシリアライズ後にnullになってしまいます。サービスパラメータは常にnullですが、トレースで確認できます

alertXMLノードには、トレースからわかるように、XMLドキュメントが文字列として含まれています。サービスコードでは、このalertXML文字列は常にnullです。このXML-as-a-stringシナリオを処理するために必要な特別な処理はありますか?

これを除いて、私は物を解析できるように封筒全体を保持する方法はありますか?

おかげ

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent"> 
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system"> 
    <EventID>0</EventID> 
    <Type>3</Type> 
    <SubType Name="Information">0</SubType> 
    <Level>8</Level> 
    <TimeCreated SystemTime="2011-07-08T17:46:14.7804786Z" /> 
    <Source Name="System.ServiceModel.MessageLogging" /> 
    <Correlation ActivityID="{54a3d088-5393-45a7-ae97-0bcd636f1750}" /> 
    <Execution ProcessName="w3wp" ProcessID="3468" ThreadID="17" /> 
    <Channel/> 
    <Computer>COMPUTER</Computer> 
</System> 
<ApplicationData> 
    <TraceData> 
     <DataItem> 
      <MessageLogTraceRecord Time="2011-07-08T13:46:14.7804786-04:00" Source="TransportReceive" Type="System.ServiceModel.Channels.BufferedMessage" xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace"> 
       <HttpRequest> 
        <Method>POST</Method> 
        <QueryString></QueryString> 
        <WebHeaders> 
         <Content-Length>1807</Content-Length> 
         <Content-Type>text/xml; charset=utf-8</Content-Type> 
         <Expect>100-continue</Expect> 
         <Host>host</Host> 
         <User-Agent>Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.3623)</User-Agent> 
         <SOAPAction>"http://www.xyz.com/wsdl/ProcessXML"</SOAPAction> 
        </WebHeaders> 
       </HttpRequest> 
       <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
        <soap:Body> 
         <ProcessXML xmlns="http://www.xyz.com/wsdl/"> 
          <alertXml>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;XMLOutgoing&gt;MORE XML STRING&lt;/XMLOutgoing&gt;</alertXml> 
         </ProcessXML> 
        </soap:Body> 
       </soap:Envelope> 
      </MessageLogTraceRecord> 
     </DataItem> 
    </TraceData> 
</ApplicationData> 

EDIT: WSDLは次のとおりです。

<?xml version="1.0" encoding="UTF-8"?> 
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
        xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" 
        xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
        xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" 
        xmlns:tns="http://www.xyz.com/wsdl/" 
        xmlns:s="http://www.w3.org/2001/XMLSchema" 
        xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
        xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
        targetNamespace="http://www.xyz.com/wsdl/" 
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> 
    <wsdl:types> 
    <s:schema elementFormDefault="qualified" targetNamespace="http://www.xyz.com/wsdl/"> 
     <s:element name="ProcessXML"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="alertXml" type="s:string"/> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 
     <s:element name="ProcessXMLResponse"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="ProcessXMLResult"> 
       <s:complexType mixed="true"> 
       <s:sequence> 
        <s:any/> 
       </s:sequence> 
       </s:complexType> 
      </s:element> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 
    </s:schema> 
    </wsdl:types> 
    <wsdl:message name="ProcessXMLSoapIn"> 
    <wsdl:part name="parameters" element="tns:ProcessXML"/> 
    </wsdl:message> 
    <wsdl:message name="ProcessXMLSoapOut"> 
    <wsdl:part name="parameters" element="tns:ProcessXMLResponse"/> 
    </wsdl:message> 
    <wsdl:message name="ProcessXMLHttpGetIn"> 
    <wsdl:part name="alertXml" type="s:string"/> 
    </wsdl:message> 
    <wsdl:message name="ProcessXMLHttpGetOut"> 
    <wsdl:part name="Body"/> 
    </wsdl:message> 
    <wsdl:message name="ProcessXMLHttpPostIn"> 
    <wsdl:part name="alertXml" type="s:string"/> 
    </wsdl:message> 
    <wsdl:message name="ProcessXMLHttpPostOut"> 
    <wsdl:part name="Body"/> 
    </wsdl:message> 
    <wsdl:portType name="GenericServiceSoap"> 
    <wsdl:operation name="ProcessXML"> 
     <wsdl:input message="tns:ProcessXMLSoapIn"/> 
     <wsdl:output message="tns:ProcessXMLSoapOut"/> 
    </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:portType name="GenericServiceHttpGet"> 
    <wsdl:operation name="ProcessXML"> 
     <wsdl:input message="tns:ProcessXMLHttpGetIn"/> 
     <wsdl:output message="tns:ProcessXMLHttpGetOut"/> 
    </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:portType name="GenericServiceHttpPost"> 
    <wsdl:operation name="ProcessXML"> 
     <wsdl:input message="tns:ProcessXMLHttpPostIn"/> 
     <wsdl:output message="tns:ProcessXMLHttpPostOut"/> 
    </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="GenericServiceSoap" type="tns:GenericServiceSoap"> 
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> 
    <wsdl:operation name="ProcessXML"> 
     <soap:operation soapAction="http://www.xyz.com/wsdl/ProcessXML" style="document"/> 
     <wsdl:input> 
     <soap:body use="literal"/> 
     </wsdl:input> 
     <wsdl:output> 
     <soap:body use="literal"/> 
     </wsdl:output> 
    </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:binding name="GenericServiceSoap12" type="tns:GenericServiceSoap"> 
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/> 
    <wsdl:operation name="ProcessXML"> 
     <soap12:operation soapAction="http://www.xyz.com/wsdl/ProcessXML" style="document"/> 
     <wsdl:input> 
     <soap12:body use="literal"/> 
     </wsdl:input> 
     <wsdl:output> 
     <soap12:body use="literal"/> 
     </wsdl:output> 
    </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:binding name="GenericServiceHttpGet" type="tns:GenericServiceHttpGet"> 
    <http:binding verb="GET"/> 
    <wsdl:operation name="ProcessXML"> 
     <http:operation location="/ProcessXML"/> 
     <wsdl:input> 
     <http:urlEncoded/> 
     </wsdl:input> 
     <wsdl:output> 
     <mime:content part="Body" type="text/xml"/> 
     </wsdl:output> 
    </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:binding name="GenericServiceHttpPost" type="tns:GenericServiceHttpPost"> 
    <http:binding verb="POST"/> 
    <wsdl:operation name="ProcessXML"> 
     <http:operation location="/ProcessXML"/> 
     <wsdl:input> 
     <mime:content type="application/x-www-form-urlencoded"/> 
     </wsdl:input> 
     <wsdl:output> 
     <mime:content part="Body" type="text/xml"/> 
     </wsdl:output> 
    </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="GenericService"> 
    </wsdl:service> 
</wsdl:definitions> 

サービスコードの骨格は次のとおりです。

Public Function ProcessXML(request As ProcessXMLRequest) As ProcessXMLResponse Implements GenericServiceSoap.ProcessXML 
    'request.Body is a non-null object but request.Body.alertXml is null 
End Function 
+0

をここでXMLの動作パラメータのためのWSDLは次のようになります。あなたの質問に答えを得るためにWSDL。また、サービスコードが役立ちます。サービス操作は次のようになるはずです: 'public voidOrResponseTypeOfSomeSort ProcessXML(XmlElement alertXml)' –

答えて

1

WCFのDataContractでXMLをパラメータまたはプロパティとして送信するには、.NETタイプのパラメータまたはプロパティに対してXmlElementを使用する必要があります。 WSDLに基づいて、alertXmlはWCFによってXMLではなく文字列としてシリアル化されます。 、すべてのWSDLがどのように見えるかを参照してください。このようなサービスを実装するには

<xs:element name="alertXml" nillable="true" minOccurs="0"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:any minOccurs="0" processContents="lax"/> 
     </xs:sequence> 
    </xs:complexType> 
</xs:element> 

:あなたが追加する必要があります

[ServiceContract] 
public interface IService1 
{ 

    [OperationContract] 
    string ProcessXml(XmlElement alertXml); 

    [OperationContract] 
    string ProcessSomeXml(ProcessXMLRequest xmlRequest); 
} 

[DataContract] 
public class ProcessXMLRequest 
{ 
    public XmlElement someXml { get; set; } 
} 

//Service implementation 
public class Service1 : IService1 
{ 
    public string ProcessXml(XmlElement alertXml) 
    { 
     XmlNode xmlToProcess = GetXmlToProcess(alertXml); 

     return string.Format("You entered: {0}", xmlToProcess.InnerText); 
    } 

    public string ProcessSomeXml(ProcessXMLRequest xmlRequest) 
    { 
     XmlNode xmlToProcess = GetXmlToProcess(xmlRequest.someXml); 

     return string.Format("You entered some: {0}", xmlToProcess.InnerText); 
    } 

    private XmlNode GetXmlToProcess(XmlElement alertXml) 
    { 
     var xmlToProcess = alertXml as XmlNode; 

     if (xmlToProcess == null) 
     { 
      var x = new XmlDocument(); 
      x.LoadXml("<root>XML was null</root>"); 
      xmlToProcess = x; 
     } 
     return xmlToProcess; 
    } 
} 
+0

wsdlを修正してalertXml定義を文字列からXML要素に変更し、svcutilでサービスを再生成しました。 AlertXmlはコード内でXmlElement型として認識されますが、まだnullになっています。 – Hc5kphUXpR

+0

通常、WCFにパラメータが設定されていないように見える場合、実際にはメッセージの内容とWCFが検索しようとしている内容が一致しません。データコントラクトメンバはデフォルトでは「オプション」なので、WCFが一致する値を見つけられない場合はnullに設定されます。私はサンプルのクライアントとサービスを作成してXMLを送受信するようにして、すべてがどのように接続されるべきかを知っています。次に、データと操作契約をサンプルに追加して、変更が必要な場合があるかどうかを確認します。 –

+0

問題は何も変更できないことです。これは、サードパーティのwsdlに基づいて実装しているサービスです。彼らが送信しているものがその定義に合致しないことに同意するならば、それをどう操作するかを理解するだけです。どのような方法でも、私は生の封筒に入って、それを解析することができますか? – Hc5kphUXpR

関連する問題