Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataContract containing IList<struct> produces invalid WSDL #346

Closed
bartbovendeerdt opened this issue Oct 24, 2019 · 5 comments
Closed

DataContract containing IList<struct> produces invalid WSDL #346

bartbovendeerdt opened this issue Oct 24, 2019 · 5 comments
Labels

Comments

@bartbovendeerdt
Copy link

bartbovendeerdt commented Oct 24, 2019

If you have a DataContract containing a property of type IList<T> where T is a struct, the WSDL that is generated is invalid.

Example

    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        void Do(DTO input);
    }

    public class MyService : IMyService
    {
        public void Do(DTO input)
        {
        }
    }

    [DataContract]
    public class DTO
    {
        [DataMember]
        public IList<AnyStruct> MyStructs { get; set; }
    }

    [DataContract]
    public struct AnyStruct
    {
    }

The code above will yield the following WSDL.

Please note the name attribute has no value.

<xs:complexType xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/" name="ArrayOfAnyStruct">
   <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="" type="xs:"/>
   </xs:sequence>
</xs:complexType>

Adding a [FaultContract(typeof(InvalidOperationException))] attribute will also cause this behavior.

The WSDL cannot be imported into the WCF Test Client or Visual Studio 2019. Given that in the actual problem case, I do not own the type, is there any way around this?

Thanks in advance,
-Bart

Full WSDL

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:http="http://schemas.microsoft.com/ws/06/2004/policy/http" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 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:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://tempuri.org/" name="MyService">
   <wsdl:types>
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
         <xs:import namespace="http://schemas.datacontract.org/2004/07/WebApplication1.Service" />
         <xs:element name="Do">
            <xs:complexType>
               <xs:sequence>
                  <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/WebApplication1.Service" minOccurs="0" name="input" nillable="true" type="q1:DTO" />
               </xs:sequence>
            </xs:complexType>
         </xs:element>
         <xs:element name="DoResponse">
            <xs:complexType>
               <xs:sequence />
            </xs:complexType>
         </xs:element>
      </xs:schema>
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/">
         <xs:element name="anyType" nillable="true" type="xs:anyType" />
         <xs:element name="anyURI" nillable="true" type="xs:anyURI" />
         <xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />
         <xs:element name="boolean" nillable="true" type="xs:boolean" />
         <xs:element name="byte" nillable="true" type="xs:byte" />
         <xs:element name="dateTime" nillable="true" type="xs:dateTime" />
         <xs:element name="decimal" nillable="true" type="xs:decimal" />
         <xs:element name="double" nillable="true" type="xs:double" />
         <xs:element name="float" nillable="true" type="xs:float" />
         <xs:element name="int" nillable="true" type="xs:int" />
         <xs:element name="long" nillable="true" type="xs:long" />
         <xs:element name="QName" nillable="true" type="xs:QName" />
         <xs:element name="short" nillable="true" type="xs:short" />
         <xs:element name="string" nillable="true" type="xs:string" />
         <xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte" />
         <xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt" />
         <xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong" />
         <xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort" />
         <xs:element name="char" nillable="true" type="tns:char" />
         <xs:simpleType name="char">
            <xs:restriction base="xs:int" />
         </xs:simpleType>
         <xs:element name="duration" nillable="true" type="tns:duration" />
         <xs:simpleType name="duration">
            <xs:restriction base="xs:duration">
               <xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?" />
               <xs:minInclusive value="-P10675199DT2H48M5.4775808S" />
               <xs:maxInclusive value="P10675199DT2H48M5.4775807S" />
            </xs:restriction>
         </xs:simpleType>
         <xs:element name="guid" nillable="true" type="tns:guid" />
         <xs:simpleType name="guid">
            <xs:restriction base="xs:string">
               <xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" />
            </xs:restriction>
         </xs:simpleType>
         <xs:attribute name="FactoryType" type="xs:QName" />
         <xs:attribute name="Id" type="xs:ID" />
         <xs:attribute name="Ref" type="xs:IDREF" />
      </xs:schema>
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:tns="http://schemas.datacontract.org/2004/07/WebApplication1.Service" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/WebApplication1.Service">
         <xs:import namespace="http://schemas.datacontract.org/2004/07/System" />
         <xs:import namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
         <xs:complexType name="DTO">
            <xs:sequence>
               <xs:element minOccurs="0" name="MyStructs" nillable="true" type="tns:ArrayOfAnyStruct" />
            </xs:sequence>
         </xs:complexType>
         <xs:element name="DTO" nillable="true" type="tns:DTO" />
         <xs:complexType name="ArrayOfAnyStruct">
            <xs:sequence>
               <xs:element minOccurs="0" maxOccurs="unbounded" name="" type="xs:" />
            </xs:sequence>
         </xs:complexType>
         <xs:element name="ArrayOfAnyStruct" nillable="true" type="tns:ArrayOfAnyStruct" />
         <xs:complexType name="AnyStruct">
            <xs:sequence />
         </xs:complexType>
         <xs:element name="AnyStruct" nillable="true" type="tns:AnyStruct" />
      </xs:schema>
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
         <xs:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
      </xs:schema>
   </wsdl:types>
   <wsdl:message name="IMyService_Do_InputMessage">
      <wsdl:part name="parameters" element="tns:Do" />
   </wsdl:message>
   <wsdl:message name="IMyService_Do_OutputMessage">
      <wsdl:part name="parameters" element="tns:DoResponse" />
   </wsdl:message>
   <wsdl:portType name="IMyService">
      <wsdl:operation name="Do">
         <wsdl:input wsam:Action="http://tempuri.org/IMyService/Do" message="tns:IMyService_Do_InputMessage" />
         <wsdl:output wsam:Action="http://tempuri.org/IMyService/DoResponse" message="tns:IMyService_Do_OutputMessage" />
      </wsdl:operation>
   </wsdl:portType>
   <wsdl:binding name="BasicHttpBinding" type="tns:IMyService">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
      <wsdl:operation name="Do">
         <soap:operation soapAction="http://tempuri.org/IMyService/Do" style="document" />
         <wsdl:input>
            <soap:body use="literal" />
         </wsdl:input>
         <wsdl:output>
            <soap:body use="literal" />
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:service name="MyService">
      <wsdl:port name="BasicHttpBinding" binding="tns:BasicHttpBinding">
         <soap:address location="http://localhost:5000/MyService.svc" />
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>
kotovaleksandr pushed a commit to kotovaleksandr/SoapCore that referenced this issue Dec 10, 2019
kotovaleksandr added a commit that referenced this issue Dec 10, 2019
DataContract containing IList<struct> produces invalid WSDL #346
@bartbovendeerdt
Copy link
Author

bartbovendeerdt commented Jan 7, 2020

@kotovaleksandr While the original issue is gone, which was the empty name attribute, there is still an issue with the setup above not generating a proper WSDL.

Also, FaultContracts are not working with a similar message.

Message:

Error: Cannot obtain Metadata from https://localhost:44366/mex If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address.  For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error    URI: https://localhost:44366/mex    Metadata contains a reference that cannot be resolved: 'https://localhost:44366/mex'.    The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.HTTP GET Error    URI: https://localhost:44366/mex    The document at the url https://localhost:44366/mex was not recognized as a known document type.The error message from each known type may help you fix the problem:- Report from 'XML Schema' is 'The root element of a W3C XML Schema should be <schema> and its namespace should be 'http://www.w3.org/2001/XMLSchema'.'.- Report from 'DISCO Document' is 'Discovery document at the URL https://localhost:44366/mex could not be found.'.  - The document format is not recognized.- Report from 'WSDL Document' is 'There is an error in XML document (1, 4380).'.  - Namespace prefix 'q1' is not defined.

Still not valid WSDL to use in the WCF Test Client.

Full WSDL

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" 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:http="http://schemas.microsoft.com/ws/06/2004/policy/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" targetNamespace="http://tempuri.org/" name="MyService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <wsdl:types>
        <xs:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">
            <xs:import namespace="http://schemas.datacontract.org/2004/07/WebApplication3" />
            <xs:element name="Do">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="input" nillable="true" type="q1:DTO" xmlns:q1="http://schemas.datacontract.org/2004/07/WebApplication3" />
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="DoResponse">
                <xs:complexType>
                    <xs:sequence />
                </xs:complexType>
            </xs:element>
        </xs:schema>
        <xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/">
            <xs:element name="anyType" nillable="true" type="xs:anyType" />
            <xs:element name="anyURI" nillable="true" type="xs:anyURI" />
            <xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />
            <xs:element name="boolean" nillable="true" type="xs:boolean" />
            <xs:element name="byte" nillable="true" type="xs:byte" />
            <xs:element name="dateTime" nillable="true" type="xs:dateTime" />
            <xs:element name="decimal" nillable="true" type="xs:decimal" />
            <xs:element name="double" nillable="true" type="xs:double" />
            <xs:element name="float" nillable="true" type="xs:float" />
            <xs:element name="int" nillable="true" type="xs:int" />
            <xs:element name="long" nillable="true" type="xs:long" />
            <xs:element name="QName" nillable="true" type="xs:QName" />
            <xs:element name="short" nillable="true" type="xs:short" />
            <xs:element name="string" nillable="true" type="xs:string" />
            <xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte" />
            <xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt" />
            <xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong" />
            <xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort" />
            <xs:element name="char" nillable="true" type="tns:char" />
            <xs:simpleType name="char">
                <xs:restriction base="xs:int" />
            </xs:simpleType>
            <xs:element name="duration" nillable="true" type="tns:duration" />
            <xs:simpleType name="duration">
                <xs:restriction base="xs:duration">
                    <xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?" />
                    <xs:minInclusive value="-P10675199DT2H48M5.4775808S" />
                    <xs:maxInclusive value="P10675199DT2H48M5.4775807S" />
                </xs:restriction>
            </xs:simpleType>
            <xs:element name="guid" nillable="true" type="tns:guid" />
            <xs:simpleType name="guid">
                <xs:restriction base="xs:string">
                    <xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" />
                </xs:restriction>
            </xs:simpleType>
            <xs:attribute name="FactoryType" type="xs:QName" />
            <xs:attribute name="Id" type="xs:ID" />
            <xs:attribute name="Ref" type="xs:IDREF" />
        </xs:schema>
        <xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/WebApplication3" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/WebApplication3" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">
            <xs:import namespace="http://schemas.datacontract.org/2004/07/System" />
            <xs:import namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
            <xs:complexType name="DTO" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">
                <xs:sequence>
                    <xs:element minOccurs="0" name="MyStructs" nillable="true" type="tns:ArrayOfAnyStruct" />
                </xs:sequence>
            </xs:complexType>
            <xs:element name="DTO" nillable="true" type="tns:DTO" />
            <xs:complexType name="ArrayOfAnyStruct" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">
                <xs:sequence>
                    <xs:element minOccurs="0" maxOccurs="unbounded" name="AnyStruct" type="q1:AnyStruct" />
                </xs:sequence>
            </xs:complexType>
            <xs:element name="ArrayOfAnyStruct" nillable="true" type="tns:ArrayOfAnyStruct" />
            <xs:complexType name="AnyStruct" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">
                <xs:annotation>
                    <xs:appinfo>
                        <IsValueType xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</IsValueType>
                    </xs:appinfo>
                </xs:annotation>
                <xs:sequence />
            </xs:complexType>
            <xs:element name="AnyStruct" nillable="true" type="tns:AnyStruct" />
        </xs:schema>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <xs:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="IMyService_Do_InputMessage">
        <wsdl:part name="parameters" element="tns:Do" />
    </wsdl:message>
    <wsdl:message name="IMyService_Do_OutputMessage">
        <wsdl:part name="parameters" element="tns:DoResponse" />
    </wsdl:message>
    <wsdl:portType name="IMyService">
        <wsdl:operation name="Do">
            <wsdl:input wsam:Action="http://tempuri.org/IMyService/Do" message="tns:IMyService_Do_InputMessage" />
            <wsdl:output wsam:Action="http://tempuri.org/IMyService/DoResponse" message="tns:IMyService_Do_OutputMessage" />
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="BasicHttpBinding" type="tns:IMyService">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="Do">
            <soap:operation soapAction="http://tempuri.org/IMyService/Do" style="document" />
            <wsdl:input>
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="MyService">
        <wsdl:port name="BasicHttpBinding" binding="tns:BasicHttpBinding">
            <soap:address location="https://localhost:44366/mex" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

kotovaleksandr pushed a commit to kotovaleksandr/SoapCore that referenced this issue Jan 10, 2020
kotovaleksandr added a commit that referenced this issue Jan 10, 2020
DataContract containing IList<struct> produces invalid WSDL #346
@kotovaleksandr
Copy link
Member

@bartbovendeerdt Check again on develop branch, please

@bartbovendeerdt
Copy link
Author

@kotovaleksandr No, it still comes back with an error.

Invalid name character in 'xmlns:q1'. The ':' character, hexadecimal value 0x3A, cannot be included in a name.

kotovaleksandr added a commit that referenced this issue Mar 12, 2020
#346: DataContract containing IList<struct> produces invalid WSDL
@github-actions
Copy link

This issue is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale label Aug 12, 2021
@github-actions
Copy link

This issue was closed because it has been inactive for 14 days since being marked as stale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants