0

我创建了一个 Web 服务客户端,编译了一个 WSDL,除了调用 Logon 方法后的空属性(ResponseCode 等为空)外,一切正常。

我有一条响应 SOAP 消息:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sas="http://ws.test.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <sas:LogonResponse>
         <SessionID>19790</SessionID>
         <ResponseCode>0</ResponseCode>
         <ResponseMessage>Logon OK</ResponseMessage>
      </sas:LogonResponse>
   </soapenv:Body>
</soapenv:Envelope>

此方法的 WSDL 部分如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:sas="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://ws.test.com/" xmlns:ns="http://ws.test.com/" targetNamespace="http://ws.test.com/">
    <wsdl:types>
        <sas:schema xmlns:sas="http://www.w3.org/2001/XMLSchema" targetNamespace="http://ws.test.com/" elementFormDefault="qualified">
            <sas:element name="Logon">
                <sas:complexType>
                    <sas:sequence>
                        <sas:element name="Username" type="sas:string" nillable="false"/>
                        <sas:element name="Password" type="sas:string" nillable="false"/>
                    </sas:sequence>
                </sas:complexType>
            </sas:element>
            <sas:element name="LogonResponse">
                <sas:complexType>
                    <sas:sequence>
                        <sas:element name="SessionID" type="sas:long" nillable="false"/>
                        <sas:element name="ResponseCode" type="sas:integer" nillable="false"/>
                        <sas:element name="ResponseMessage" type="sas:string" nillable="false"/>
                    </sas:sequence>
                </sas:complexType>
            </sas:element>
        </sas:schema>
    </wsdl:types>

    <wsdl:message name="LogonRequest">
        <wsdl:part name="Logon" element="tns:Logon"/>
    </wsdl:message>
    <wsdl:message name="LogonResponse">
        <wsdl:part name="LogonResponse" element="tns:LogonResponse"/>
    </wsdl:message>

    <wsdl:portType name="rrrwebservice">
        <wsdl:operation name="Logon">
            <wsdl:input message="tns:LogonRequest"/>
            <wsdl:output message="tns:LogonResponse"/>
        </wsdl:operation>
    </wsdl:portType>

    <wsdl:binding name="mvcBinding" type="tns:rrrwebservice">
        <soap:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="Logon">
            <soap:operation
                soapAction="http://ws.test.com/Logon" />
            <wsdl:input>
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>

    <wsdl:service name="RRRWebService">
        <wsdl:port name="RRRWebService" binding="tns:mvcBinding">
            <soap:address location="http://172.6.2.14:8008/"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

无法弄清楚问题所在。我通过在 Visual Studio 2008 中选择“添加服务参考”来编译它。任何意见和答案将不胜感激!谢谢。

4

1 回答 1

0

半途而废的 MS 实现对格式非常挑剔。它需要像这里的 ns:tag 符号

    <?xml version="1.0" encoding="UTF-8"?>
    <soap:Envelope soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soapenc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <soap:Body>
            <ns2:SessionCreateResponse xmlns:ns2="http://www.otrs.org/TicketConnector/">
                <SessionID>3efVfYNzxB2z8wUKQRPeVYc7K9JddAlf</SessionID>
            </ns2:SessionCreateResponse>
        </soap:Body>
    </soap:Envelope>

我收到了一个用 Perl 编写的名为 OTRS 的应用程序的响应。它创建了这样的响应:

    <soap:Envelope soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soapenc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <soap:Body>
          <SessionCreateResponse xmlns="http://www.otrs.org/TicketConnector/">
             <SessionID>juFUKqABresNemTCYtPHFiLFWgjJ4QNj</SessionID>
          </SessionCreateResponse>
       </soap:Body>
    </soap:Envelope>

MS不会有它。乱用 XmlSchemaForm.Unqualified/None 什么也不做。我不得不修改 Reference.cs 中的覆盖来重新格式化消息。

    protected override XmlReader GetReaderForMessage(SoapClientMessage message, int bufferSize)
    {
        var newStream = new MemoryStream();
        var orgStream = message.Stream;
        byte[] buf = new byte[bufferSize];
        orgStream.Read(buf, 0, bufferSize);
        string response = Encoding.UTF8.GetString(buf);            
        int pos = response.IndexOf("Response xmlns=");
        if (pos == -1)
        {
            pos = response.IndexOf("Response>");
            if (pos > -1)
                response = response.Insert(pos + 8, " xmlns=\"http://tempuri.org/\"");
        }
        if (pos > -1)
        {
            int pos2 = pos + 8;
            int pos3 = pos + 14;
            while (response[--pos-1] != '<') ;
            string tagName = response.Substring(pos, pos2 - pos);
            response = response.Insert(pos3, ":ns2").Insert(pos, "ns2:");
            int pos4 = response.IndexOf("</" + tagName) + 2;
            response = response.Insert(pos4, "ns2:");
        }
        StreamWriter sw = new StreamWriter(newStream, Encoding.UTF8);
        sw.WriteLine(response);
        sw.Flush();
        newStream.Position = 0;
        return new System.Xml.XmlTextReader(newStream);
    }
于 2016-02-11T00:12:09.687 回答