In a WCF project we recently received a WSDL from our customer that we needed to build a client/proxy to.
So we used svcutil.exe to generate the C#-code we wanted.
To our surprise, the code did not contain the types of the contract we expected, but something like this:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://MyService.namespace", ConfigurationName="MyService")]
public interface MyService
{
// CODEGEN: Generating message contract since the wrapper namespace (http://MyTypes.namespace) of message myMethodRequest does not match the default value (http://MyService.namespace)
[System.ServiceModel.OperationContractAttribute(Action="myMethod", ReplyAction="*")]
myMethodResponse myMethod(myMethodRequest request);
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="Request", WrapperNamespace="http://MyTypes.namespace", IsWrapped=true)]
public partial class myMethodRequest
{
public myMethodRequest()
{
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="Response", WrapperNamespace="http://MyTypes.namespace", IsWrapped=true)]
public partial class myMethodResponse
{
public myMethodResponse()
{
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface MyServiceChannel : MyService, System.ServiceModel.IClientChannel
{
} |
After a long time of experimenting around and not getting a clue, I tried the good old wsdl.exe, which gave me the following:
Microsoft (R) Web Services Description Language Utility [Microsoft (R) .NET Framework, Version 2.0.50727.312] Copyright (C) Microsoft Corporation. All rights reserved. Error: Unable to import binding 'MyService_SoapHttp_Binding' from namespace 'http://MyService.namespace'. - Unable to import operation 'myMethod'. - These members may not be derived.
If you would like more help, please type "wsdl /?". |
OK, so there was an issue with abstract types? Indeed, the WSDL contained abstract complexTypes and a complexType extending that abstract type for both, request and response.
I then simplified it by just making one of those types a simple type. And suddenly it worked. However, this was not satisfying.
When playing around with it, I ended up at the message parts which were like this:
<message name="MyServiceRequest"> <part element="myns:Request" name="parameters" /> </message> <message name="MyServiceResponse"> <part element="myns:Response" name="parameters" /> </message> |
At one point I changed one of the name attributes of the message part to something else, say:
<part element="myns:Response" name="parametersResponse" /> |
and suddenly it worked.
I changed it back and did the same for the request.
So, I thought, it was a problem with the name property being duplicated. However, looking at other examples proved that this was not the case.
A section saying
<message name="MyServiceRequest"> <part element="myns:Request" name="anythingNotparameters" /> </message> <message name="MyServiceResponse"> <part element="myns:Response" name="anythingNotparameters" /> </message> |
would work just fine, we found.
It is a weird combination of: abstract types used in both request and response and the names of the message parts of request and response being both "parameters".
Here is the full "problem" wsdl to play with. Have fun.
<?xml version="1.0" encoding="UTF-8"?> <definitions name="MyService" targetNamespace="http://MyService.namespace" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:myns="http://MyTypes.namespace" xmlns:sdx="http://ServiceDescription.namespace" xmlns:tns="http://MyService.namespace" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <types> <schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://MyTypes.namespace" version="1.1" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:myns="http://MyTypes.namespace"> <complexType abstract="true" name="RequestAbstractType"> <attribute name="RequestID" type="integer" use="required"/> </complexType> <element name="Request" type="myns:RequestType"/> <complexType name="RequestType"> <complexContent> <extension base="myns:RequestAbstractType"> <sequence> <element name="RequestNode" type="string"/> </sequence> </extension> </complexContent> </complexType> <complexType abstract="true" name="ResponseAbstractType"> <attribute name="ResponseID" type="integer" use="required"/> </complexType> <element name="Response" type="myns:ResponseType"/> <complexType name="ResponseType"> <complexContent> <extension base="myns:ResponseAbstractType"> <sequence> <element name="ResponseNode" type="string"/> </sequence> </extension> </complexContent> </complexType> </schema> </types> <message name="MyServiceRequest"> <part element="myns:Request" name="parameters" /> </message> <message name="MyServiceResponse"> <part element="myns:Response" name="parameters" /> </message> <portType name="MyService"> <operation name="myMethod"> <input message="tns:MyServiceRequest"/> <output message="tns:MyServiceResponse"/> </operation> </portType> <binding name="MyService_SoapHttp_Binding" type="tns:MyService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="myMethod"> <soap:operation soapAction="myMethod"/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="MyServiceProvider"> <serviceKey xmlns="http://MyServiceProvider.namespace">uddi:myservices.org:MyServiceProvider</serviceKey> <port binding="tns:MyService_SoapHttp_Binding" name="MyService_Http_Port"> <soap:address location="http://myserver:12345/soap/MyServiceProvider"/> </port> <port binding="tns:MyService_SoapHttp_Binding" name="MyService_Https_Port"> <soap:address location="https://myserver:12346/soap/MyServiceProvider"/> </port> </service> </definitions> |
The relevant samples are available for download as a .zip attachment.
Posted
Feb 02 2007, 02:16 AM
by
Andreas Erben