Java工具创建的WSDL文件存在WCF序列化问题

Java工具创建的WSDL文件存在WCF序列化问题,java,wcf,serialization,wsdl,interop,Java,Wcf,Serialization,Wsdl,Interop,我的团队的任务是让几个内部开发的.NET客户端应用程序连接到一些新的Java web服务。Java web服务是供应商提供的第三方WSDL文件,我们的团队修改/控制该文件的能力有限……这意味着我们可能有权要求供应商对WSDL进行轻微调整,但重大更改可能不可行或难以请求 也就是说,我们正试图利用WCF/.NET 4.0生成客户端所需的.NET代理类文件。代理客户端类文件生成过程执行时不会出现问题 问题是当我们试图在客户端应用程序中使用代理类文件时。我已经通过web跟踪工具Fiddler验证了原始S

我的团队的任务是让几个内部开发的.NET客户端应用程序连接到一些新的Java web服务。Java web服务是供应商提供的第三方WSDL文件,我们的团队修改/控制该文件的能力有限……这意味着我们可能有权要求供应商对WSDL进行轻微调整,但重大更改可能不可行或难以请求

也就是说,我们正试图利用WCF/.NET 4.0生成客户端所需的.NET代理类文件。代理客户端类文件生成过程执行时不会出现问题

问题是当我们试图在客户端应用程序中使用代理类文件时。我已经通过web跟踪工具Fiddler验证了原始SOAP消息请求无法通过网络发送到服务器

我在尝试调用相关web服务方法时收到的特定.NET异常消息如下所示:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="QueryPBOT_MXWO_OS", WrapperNamespace="http://www.ibm.com/maximo", IsWrapped=true)]
public partial class QueryPBOT_MXWO_OSRequest {

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=0)]
    public ConsoleApplication7.wsMaximo.PBOT_MXWO_OSQueryType PBOT_MXWO_OSQuery;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=1)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string baseLanguage;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=2)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string transLanguage;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=3)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string messageID;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=4)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string maximoVersion;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=5)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    [System.ComponentModel.DefaultValueAttribute(false)]
    public bool uniqueResult;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=6)]
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="positiveInteger")]
    public string maxItems;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=7)]
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="integer")]
    [System.ComponentModel.DefaultValueAttribute("0")]
    public string rsStart;

    public QueryPBOT_MXWO_OSRequest() {
    }

    public QueryPBOT_MXWO_OSRequest(ConsoleApplication7.wsMaximo.PBOT_MXWO_OSQueryType PBOT_MXWO_OSQuery, string baseLanguage, string transLanguage, string messageID, string maximoVersion, bool uniqueResult, string maxItems, string rsStart) {
        this.PBOT_MXWO_OSQuery = PBOT_MXWO_OSQuery;
        this.baseLanguage = baseLanguage;
        this.transLanguage = transLanguage;
        this.messageID = messageID;
        this.maximoVersion = maximoVersion;
        this.uniqueResult = uniqueResult;
        this.maxItems = maxItems;
        this.rsStart = rsStart;
    }
}
未处理System.InvalidOperationException Message=XmlSerializer属性System.Xml.Serialization.XmlAttributeAttribute在baseLanguage中无效。当IsWrapped为true时,仅支持XmlElement、XmlArray、XmlArrayItem、XmlAnyAttribute和XmlAnyElement属性。 Source=系统服务模型

当我检查.NET自动生成的代理类文件Reference.cs时,我注意到web服务方法的请求和响应消息如下所示:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="QueryPBOT_MXWO_OS", WrapperNamespace="http://www.ibm.com/maximo", IsWrapped=true)]
public partial class QueryPBOT_MXWO_OSRequest {

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=0)]
    public ConsoleApplication7.wsMaximo.PBOT_MXWO_OSQueryType PBOT_MXWO_OSQuery;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=1)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string baseLanguage;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=2)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string transLanguage;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=3)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string messageID;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=4)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string maximoVersion;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=5)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    [System.ComponentModel.DefaultValueAttribute(false)]
    public bool uniqueResult;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=6)]
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="positiveInteger")]
    public string maxItems;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=7)]
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="integer")]
    [System.ComponentModel.DefaultValueAttribute("0")]
    public string rsStart;

    public QueryPBOT_MXWO_OSRequest() {
    }

    public QueryPBOT_MXWO_OSRequest(ConsoleApplication7.wsMaximo.PBOT_MXWO_OSQueryType PBOT_MXWO_OSQuery, string baseLanguage, string transLanguage, string messageID, string maximoVersion, bool uniqueResult, string maxItems, string rsStart) {
        this.PBOT_MXWO_OSQuery = PBOT_MXWO_OSQuery;
        this.baseLanguage = baseLanguage;
        this.transLanguage = transLanguage;
        this.messageID = messageID;
        this.maximoVersion = maximoVersion;
        this.uniqueResult = uniqueResult;
        this.maxItems = maxItems;
        this.rsStart = rsStart;
    }
}
我知道阅读这篇文章的人会想看到我们正在尝试使用的实际WSDL文件,但它相当大,我担心它的大小会使查明错误变得非常困难

我希望自动生成的客户端代理文件和.NET异常能够帮助人们认识到这个WCF序列化问题

我们已经从Java供应商处确认,他们生成的WSDL的样式是doc-literal。在互联网上做了一些研究之后,似乎WCF默认为。翻译带有doc literal包装的WSDL文件,这至少可以部分解释为什么我们会看到WSDL文件存在WCF序列化问题

通过反复试验,我发现代理类文件中的以下属性装饰器是序列化问题背后的罪魁祸首:

[System.Xml.Serialization.XmlAttributeAttribute()]

如果我在代理类文件中注释掉该属性的所有实例并重新运行我的客户端应用程序,SOAP消息将成功通过网络发送,并且我将从服务器返回一个有效的web服务响应

这个修复比什么都没有好,但我更喜欢一个解决方案,它不需要我自己或我的团队中的任何人不断调整这些.NET自动生成的代理类文件

我想知道我是否可以通过各种WCF工具或修改WSDL文件来阻止[System.Xml.Serialization.XmlAttributeAttribute()]应用于我的请求和响应对象属性

或者至少是一个高级描述,说明为什么我们在.NET中看到这种带有JavaWSDL文件的序列化行为

提前感谢,,
John

根据生成的代码,您的Java服务似乎需要如下请求:

<s:Envelope xmlns:s="...">
  ...
  <s:Body>
    <QueryPBOT_MXWO_OS xmlns="http://www.ibm.com/maximo" baseLanguage="..." transLanguage="..." ...>
      <PBOT_MXWO_OSQuery>
        ...
      </PBOT_MXWO_OSQuery>
    </QueryPBOT_MXWO_OS>
  </s:Body>
</s:Envelope>
在启用/wrapped选项的情况下使用svcutil.exe实用程序生成代理类

这将创建与通过VisualStudio创建的类稍有不同的类,方法由Ladislav Mrnka在这里描述。在客户端使用时,生成的代理应该不会出现XmlAttribute问题

例如:

svcutil /t:code wsdl.xml /out:wsdl.cs /serializer:XmlSerializer /wrapped

以下是如何在IDE中实现Mikhail G的解决方案:

  • 在服务引用下打开Reference.svcmap
  • 下添加
    true
    ,然后保存
  • 右键单击Reference.svcmap并点击“运行自定义工具”
Visual Studio,魔法发生的地方:)

注:与VS 2015一起试用。以前的版本可能有相同的选项 与“运行自定义工具”不同的名称


根据stratovarius的回答,在VS 2017中,服务引用文件夹被连接的服务所取代,因此您必须:

  • 在Windows资源管理器中打开{project}/Connected Services文件夹
  • 使用文本编辑器查找并编辑Reference.svcmap
  • true
    添加到
    部分
  • 保存文件
  • 在VS中,右键单击已连接服务下的服务引用,然后选择“更新服务引用”

  • 这清除了我的服务呼叫中的异常

    我在.Net核心应用程序中使用外部“旧”Java生成的WSDL,而自动生成的Reference.cs对我不起作用。我必须删除
    [System.Xml.Serialization.XmlAttributeAttribute()]
    才能让它工作。

    XmlAttributeAttribute是您添加的还是由WCF生成的?XmlAttributeAttribute是由WCF工具生成的,我不明白为什么。如果工具中存在某种类型的切换以阻止创建它,或者我们可以在源WSDL文件中更改某些内容,我们可以避免调整代理类文件以使其正常工作。您有来自Java供应商的示例工作soap请求吗?Laislav,感谢您的评论,但我真正想要的是一个解决方案,在这个解决方案中,我根本不需要接触代理类文件就可以让web服务工作。如果我从代理类文件中注释掉[XmlAttribute()]的所有实例,web服务将正常工作。但在这种情况下,所有这些参数都作为元素传输。那么你需要这些参数吗?如果不是简单地从WSDL中删除它们并重新生成proxy.VS 2017(15.9.6),当我选择“更新服务引用”时,会自动从.svcmap文件中删除true。这是vs2017的一个bug吗?