65.9K
CodeProject 正在变化。 阅读更多。
Home

如何避免 SFxCannotImportAsParameters-DifferentWrapperName 错误

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2012年4月6日

CDDL

1分钟阅读

viewsIcon

8944

本技巧展示了如何修改 WSDL 文件以避免 SFxCannotImportAsParameters_DifferentWrapperName 异常,该异常在 Visual Studio 中导入 WSDL 文件时抛出。

引言

为了使用 WCF 消费 Web 服务,可以使用 Visual Studio 导入其 WSDL 描述以生成托管客户端。 在提供符合 Visual Studio 要求的 WSDL 描述时,需要考虑一些事项。

本技巧至少展示了如何解决 SFxCannotImportAsParameters_DifferentWrapperName 异常,该异常在生成的代码文件中以以下注释形式表达

"CODEGEN: 生成消息契约,因为指定消息的包装器名称与默认值不匹配。"

背景

解决方案很简单,但我花了半天时间在网上搜索,并且注意到提供的解决方案都无法满足我。 只有通过大量地尝试修改 WSDL 文件,我才找到了解决方案。

解决方案

考虑以下会引发此异常的 WSDL 文档

<?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>

这将让 Visual Studio 生成以下客户端契约(摘录)

[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 将参数和结果包装到它们自己的类中:GetWebserviceVersionRequestGetWebserviceVersionResponse

可以通过为每个 wsdl:input 元素(//wsdl:portType/wsdl:operation/wsdl:input)指定一个名称来解决该问题,例如“parameters”,以便示例中的 wsdl:portType 元素如下所示

<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>

这将让 Visual Studio 生成以下客户端契约(摘录): 

[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();
}

现在 GetWebserviceVersion 的签名更易读,并且 CODEGEN 注释消失了。

参考资料  

以下链接有所帮助,但没有提供正确的解决方案: 

© . All rights reserved.