Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / code-generation

How to avoid SFxCannotImportAsParameters-DifferentWrapperName

0.00/5 (No votes)
6 Apr 2012CDDL1 min read 8.2K  
This tip shows how to change a WSDL-file to avoid the SFxCannotImportAsParameters_DifferentWrapperName-Exception, which is thrown when importing the WSDL-file in Visual Studio

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:

XML
<?xml version="1.0" encoding="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):

C#
[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 {

    // CODEGEN: Generating message contract because the wrapper name () of the specified message "GetWebserviceVersionRequest"
    // does not match the default value (http://www.example.com/services).
    [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:

XML
<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): 

C#
[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: 

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)