为什么我的SOAP请求不正确地为子元素包含一个空的xmlns属性?

时间:2018-10-22 13:40:49

标签: c# xml soap xml-namespaces

我已经通过“添加服务参考”(简化的WSDL,包括在下面)从WSDL在Visual Studio中生成了一个c#客户端。当我使用此客户端生成对服务的请求时,它将创建具有空xmlns属性的子元素。这是一个示例请求:

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header>
        <Action s:mustUnderstand="1" 
            xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://sap.com/xi/WebService/soap1.1</Action>
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <MySearchInput xmlns="http://www.example.com/mySearch">

            <SearchDetails xmlns="">

                <CompanyName>asda</CompanyName>
            </SearchDetails>
        </MySearchInput>
    </s:Body>
</s:Envelope>

要使其成为对服务的有效请求,SearchDetails元素不应具有此空的xmls属性,它应继承其父级MySearchInput上定义的默认名称空间元件。

我可以对wsdl进行更改,以便客户端生成所需的请求XML吗?

我有一个解决方法,涉及更改Visual Studio创建的代码生成文件,但是我怀疑应该有一个更优雅的解决方案,包括更改wsdl本身?

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="MySearch_Out" targetNamespace="urn:example.mysearch" 
    xmlns:p2="http://www.example.com/mySearch" 
    xmlns:p1="urn:example.mysearch" 
    xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <wsdl:documentation/>
    <wsp:UsingPolicy wsdl:required="true"/>
    <wsp:Policy wsu:Id="OP_MySearch_Out"/>
    <wsdl:types>
        <xsd:schema targetNamespace="http://www.example.com/mySearch" 
            xmlns="http://www.example.com/mySearch" 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <xsd:element name="MySearchInput" type="MySearchInput_TYPE"/>
            <xsd:element name="MySearchOutput" type="MySearchOutput_TYPE"/>

            <xsd:complexType name="MySearchOutput_TYPE">
                <xsd:all>

                    <xsd:element name="SearchSummary" type="MySearchOutput_SearchSummary_TYPE" minOccurs="0"/>
                </xsd:all>
            </xsd:complexType>

            <xsd:complexType name="MySearchInput_TYPE">
                <xsd:all>
                    <xsd:element name="SearchDetails" type="MySearchInput_SearchDetails_TYPE" minOccurs="0"/>
                </xsd:all>
            </xsd:complexType>

            <xsd:complexType name="MySearchInput_SearchDetails_TYPE">
                <xsd:all>
                    <xsd:element name="CompanyRef" minOccurs="0">
                        <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                                <xsd:maxLength value="8"/>
                                <xsd:pattern value="[0-9A-Z]+"/>
                            </xsd:restriction>
                        </xsd:simpleType>
                    </xsd:element>
                    <xsd:element name="CompanyName" minOccurs="0">
                        <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                                <xsd:maxLength value="100"/>
                            </xsd:restriction>
                        </xsd:simpleType>
                    </xsd:element>
                </xsd:all>
            </xsd:complexType>

            <xsd:complexType name="MySearchOutput_SearchSummary_TYPE">
                <xsd:all>
                    <xsd:element name="NumberMatches" minOccurs="0">
                        <xsd:simpleType>
                            <xsd:restriction base="xsd:integer">
                                <xsd:maxInclusive value="999"/>
                            </xsd:restriction>
                        </xsd:simpleType>
                    </xsd:element>
                    <xsd:element name="CompanyRef" minOccurs="0">
                        <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                                <xsd:maxLength value="20"/>
                            </xsd:restriction>
                        </xsd:simpleType>
                    </xsd:element>
                    <xsd:element name="CompanyName" minOccurs="0">
                        <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                                <xsd:maxLength value="100"/>
                            </xsd:restriction>
                        </xsd:simpleType>
                    </xsd:element>
                </xsd:all>
            </xsd:complexType>
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="p2.MySearchInput">
        <wsdl:documentation/>
        <wsdl:part name="MySearchInput" element="p2:MySearchInput"/>
    </wsdl:message>
    <wsdl:message name="p2.MySearchOutput">
        <wsdl:documentation/>
        <wsdl:part name="MySearchOutput" element="p2:MySearchOutput"/>
    </wsdl:message>
    <wsdl:portType name="MySearch_Out">
        <wsdl:documentation/>
        <wsdl:operation name="MySearch_Out">
            <wsdl:documentation/>
            <wsp:Policy>
                <wsp:PolicyReference URI="#OP_MySearch_Out"/>
            </wsp:Policy>
            <wsdl:input message="p1:p2.MySearchInput"/>
            <wsdl:output message="p1:p2.MySearchOutput"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="MySearch_OutBinding" type="p1:MySearch_Out">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" 
            xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
        <wsdl:operation name="MySearch_Out">
            <soap:operation soapAction="http://sap.com/xi/WebService/soap1.1" 
                xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
            <wsdl:input>
                <soap:body use="literal" 
                    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" 
                    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="MySearch_OutService">
        <wsdl:port name="HTTP_Port" binding="p1:MySearch_OutBinding">
            <soap:address location="http://www.example.com/MySearch" 
                xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
        </wsdl:port>
        <wsdl:port name="HTTPS_Port" binding="p1:MySearch_OutBinding">
            <soap:address location="http://www.example.com/MySearch" 
                xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

1 个答案:

答案 0 :(得分:0)

我在另一个StackOverflow问题中找到了答案。我认为,尽管具有相同的解决方案,但该问题的具体内容可能足以确保它是一个不同的问题。

Why is Oxygen generating child elements with empty xmlns attributes?

解决方案是将elementFormDefault="qualified"添加到WSDL中的schema元素。

<xsd:schema targetNamespace="http://www.example.com/mySearch" 
            xmlns="http://www.example.com/mySearch" 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified">