服务参数始终为空,但我可以在跟踪中看到它 [英] Service parameter always null, but I can see it in the trace

查看:16
本文介绍了服务参数始终为空,但我可以在跟踪中看到它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法实现基于第三方 wsdl 的服务.第三方调用我的服务,我可以看到跟踪中的数据,但我的服务参数在反序列化后一直以空结束.

I'm having trouble implementing a service based off of a third-party wsdl. The third-party calls into my service and I can see the data in the trace, but my service parameters keep ending up null after deserialization.

从跟踪中可以看出,alertXML 节点包含一个 XML 文档作为字符串.在服务代码中,此alertXML 字符串始终为空.是否需要进行一些特殊处理来处理这种 XML-as-a-string 场景?

As you can see from the trace, the alertXML node contains a XML document as a string. In the service code, this alertXML string is always null. Is there some special processing I need to do to handle this XML-as-a-string scenario?

除此之外,有没有办法让我拿到整个信封,以便我可以解析它?

Barring that, is there any way for me to just get a hold of the whole envelope so that I can parse the thing out?

谢谢

<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>

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

推荐答案

要将 XML 作为参数或属性发送到 WCF 的 DataContract 中,您需要使用 XmlElement 作为参数或属性的 .NET 类型.根据问题中的 WSDL,alertXml 将被 WCF 序列化为字符串而不是 XML.XML 操作参数的 WSDL 如下所示:

To send XML as a parameter or a property in a DataContract in WCF you need to use XmlElement for the .NET type of the parameter or property. Based on the WSDL in the question, the alertXml will be serialized as a string not XML by WCF. Here is what the WSDL for an XML operation parameter would look like:

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

要查看所有 WSDL 应该是什么样子,请实现如下服务:

To see what all the WSDL should look like, implement a service like this:

[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;
    }
}

这篇关于服务参数始终为空,但我可以在跟踪中看到它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆