Introduction
For consuming a webservice with WCF, its WSDL-description can be imported with Visual Studio to generate a managed client. There are a few things to consider when providing manually such a Visual-Studio compliant WSDL-description.
This tip shows at least how to solve the SFxCannotImportAsParameters_DifferentWrapperName
-exception, which is expressed with the following comment in the generated code-file:
"CODEGEN: Generating message contract because the wrapper name of the specified message does not match the default value."
Background
The solution is simple, but it took me half a day to search the whole web and noticing that none of the provided solutions satisfied me. Only by playing around a lot with the WSDL-file I came to the solution.
The Solution
Considering the following WSDL-document, which raises this exception:
="1.0"="UTF-8"
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap-env="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.com/services"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/services">
<wsdl:message name="TestGetWebserviceVersionRequest"/>
<wsdl:message name="TestGetWebserviceVersionResponse">
<wsdl:part name="result" type="xsd:int"/>
</wsdl:message>
<wsdl:portType name="TestPortType">
<wsdl:operation name="GetWebserviceVersion">
<wsdl:documentation>Get the current webservice version</wsdl:documentation>
<wsdl:input message="tns:TestGetWebserviceVersionRequest"/>
<wsdl:output message="tns:TestGetWebserviceVersionResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TestBinding" type="tns:TestPortType">
<soap-env:binding xmlns:soap-env="http://schemas.xmlsoap.org/wsdl/soap/" style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetWebserviceVersion">
<soap-env:operation soapAction="http://www.hediet.de/projects/enhanced-soap-webservices/code/index.php/service/Test?method=GetWebserviceVersion" style="rpc"/>
<wsdl:input>
<soap-env:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</wsdl:input>
<wsdl:output>
<soap-env:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Test">
<wsdl:port xmlns:soap-env="http://schemas.xmlsoap.org/wsdl/soap/" name="TestPort" binding="tns:TestBinding">
<soap-env:address xmlns:soap-env="http://schemas.xmlsoap.org/wsdl/soap/" location="http://www.yourwebservice/webservice/test"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
This will let Visual Studio generate the following client-contract (extract):
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://www.example.com/services", ConfigurationName="TestWebservice.TestPortType")]
public interface TestPortType {
[System.ServiceModel.OperationContractAttribute(
Action="http://www.hediet.de/projects/enhanced-soap-webservices/code/index.php/service/Te" +
"st?method=GetWebserviceVersion", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc,
SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)]
ConsoleApplicationSoapTestClient.TestWebservice.GetWebserviceVersionResponse
GetWebserviceVersion(ConsoleApplicationSoapTestClient.TestWebservice.GetWebserviceVersionRequest request);
}
Visual Studio has wrapped the parameters and result into their own classes: GetWebserviceVersionRequest
and GetWebserviceVersionResponse
.
The problem can be solved by giving each wsdl:input-element (//wsdl:portType/wsdl:operation/wsdl:input) a name, e.g., "parameters", so that the wsdl:portType-element in the example looks as following:
<wsdl:portType name="TestPortType">
<wsdl:operation name="GetWebserviceVersion">
<wsdl:documentation>Get the current webservice version</wsdl:documentation>
<wsdl:input name="parameters" message="tns:TestGetWebserviceVersionRequest"/>
<wsdl:output message="tns:TestGetWebserviceVersionResponse"/>
</wsdl:operation>
</wsdl:portType>
This will let Visual Studio generate the following client-contract (extract):
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://www.example.com/services", ConfigurationName="TestWebservice.TestPortType")]
public interface TestPortType {
[System.ServiceModel.OperationContractAttribute(Action="http://www.example.com/services/TestPortType/parameters",
ReplyAction="http://www.example.com/services/TestPortType/GetWebserviceVersionResponse")]
[System.ServiceModel.DataContractFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc)]
[return: System.ServiceModel.MessageParameterAttribute(Name="result")]
int GetWebserviceVersion();
}
Now the signature of GetWebserviceVersion
is more readable and the CODEGEN-comment has gone.
References
The following links were helpful but did not provide the proper solution: