Operation parameter types are null in imported service metadata (WSDL)

I am trying to import a list of WCF service operations. I need to get the name of each operation, its names and parameter types, and the type of the result.

The service I'm testing this with is simple: one operation takes a parameter of type int.

WSDL:

<wsdl:definitions name="Service1" targetNamespace="http://tempuri.org/">
    <wsdl:types>
        <xsd:schema targetNamespace="http://tempuri.org/Imports">
            <xsd:import schemaLocation="http://localhost:3657/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
            <xsd:import schemaLocation="http://localhost:3657/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="IService1_GetData_InputMessage">
        <wsdl:part name="parameters" element="tns:GetData"/>
    </wsdl:message><wsdl:message name="IService1_GetData_OutputMessage">
        <wsdl:part name="parameters" element="tns:GetDataResponse"/>
    </wsdl:message>
    <wsdl:portType name="IService1">
        <wsdl:operation name="GetData">
            <wsdl:input wsaw:Action="http://tempuri.org/IService1/GetData" message="tns:IService1_GetData_InputMessage"/>
            <wsdl:output wsaw:Action="http://tempuri.org/IService1/GetDataResponse" message="tns:IService1_GetData_OutputMessage"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="BasicHttpBinding_IService1" type="tns:IService1">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="GetData">
            <soap:operation soapAction="http://tempuri.org/IService1/GetData" 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="Service1">
        <wsdl:port name="BasicHttpBinding_IService1" binding="tns:BasicHttpBinding_IService1">
            <soap:address location="http://localhost:3657/Service1.svc"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

      

xsd0 looks like this:

<xs:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
    <xs:element name="GetData">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" name="value" type="xs:int"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="GetDataResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" name="GetDataResult" nillable="true" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

      

I am using the System.ServiceModel.Description.WsdlImporter class like this:

MetadataExchangeClient mexClient = new MetadataExchangeClient(
    new Uri("http://localhost:3657/Service1.svc?singleWsdl"),
    MetadataExchangeClientMode.HttpGet);

mexClient.ResolveMetadataReferences = true;
MetadataSet metaDocs = mexClient.GetMetadata();
WsdlImporter importer = new WsdlImporter(metaDocs);

      

Next, I get a list of contracts and iterate through it:

 Collection<ContractDescription> contracts = importer.ImportAllContracts();

    foreach (ContractDescription contract in contracts)
    {
        Debug.WriteLine("Contract name:" + contract.Name);

        foreach (OperationDescription operation in contract.Operations)
        {
            Debug.WriteLine("\tOperation name:" + operation.Name);

            foreach (MessageDescription message in operation.Messages)
            {
                MessageBodyDescription body = message.Body;

                Debug.WriteLine("\t\t\tMessage wrapper name: " + body.WrapperName);

                foreach (MessagePartDescription part in body.Parts)
                {
                    Debug.WriteLine("\t\t\t\tPart name: " + part.Name);
                    Debug.WriteLine("\t\t\t\tPart type: " + part.Type);
                }

                if (body.ReturnValue != null)
                {
                    Debug.WriteLine("\t\t\t\tReturn value type: " + body.ReturnValue.Type);
                }
        }
    }
}

      

As a result, the transaction information should be printed. I am getting the following output:

Contract name: IService1
    Operation name: GetData
            Message wrapper name: GetData
                Part name: value
                Part type: 
            Message wrapper name: GetDataResponse
                Return value type: 

As you can see, the parts corresponding to the operation parameters contain null in the Type property. Likewise, the return type is also null.

I examined the contents of the contracts collection and in every place where there should be some type information, it is empty (eg OperationDescription.KnownTypes property).

I tried the approach from this question, but it fails:

foreach (object item in xmlSchema.Items)

      

where the Items collection is empty.

Does anyone know why the type information is missing? Everything else seems to be present.

Thank.

Edit: I found that the type information is present in the non-public property of the "BaseType" body part of the message. Why is it personal? Anyone access to this? (Unrelated to creating an actual proxy, which I don't want to do at this point.)

+3


source to share





All Articles