.NET WCF序列化问题

tmb*_*gmn 5 .net c# wcf xml-serialization

情况:系统A应该公开SOAP 1.2 Web服务以供系统B调用.为了让A知道消息的样子,B向A发送了一个描述消息内容的XSD.使用.NET xsd.exe工具生成存根,在此周围创建了简单的Web服务并完成了工作.

然而; 当B调用此Web服务时,A拒绝将SOAP/XML内容序列化为生成的代理类实例.我意识到这必须归结为在系统A上的Web服务端定义序列化的方式,但是无法准确找到出错的地方.

来自B的消息是什么样的(匿名) - 失败:

<ns2:Set_Out xmlns:ns2="http://a.a/1.0" xmlns:ns1="http://b.b/1.0" xmlns:ns0="http://c.c">
<Context xmlns="">
    <Foo>test</Foo>
    <Bar>test</Bar>
    ...
</Context>
Run Code Online (Sandbox Code Playgroud)

来自测试客户端(基于WSDL)的测试消息是什么样的 - 工作:

<Set_Out xmlns="http://a.a/1.0">
<Context xmlns:b="http://schemas.datacontract.org/2004/07/x.x" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <b:Foo>TEST</b:Foo>
    <b:Bar>test</b:Bar>
    ...
</Context>
Run Code Online (Sandbox Code Playgroud)

当A构建的Web服务从B接收消息时,它根本不会序列化消息.代理的对象(例如Context)是null.当它从测试客户端收到消息时,一切都正确生成.

代理上的序列化属性:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://a.a/1.0")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://a.a/1.0", IsNullable=false)]
[System.ServiceModel.MessageContract]
public partial class Set_Out {
    [System.Xml.Serialization.XmlElementAttribute(Namespace="http://a.a/1.0", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]    [System.ServiceModel.MessageBodyMember(Order=0)]
    public ContextType Context;
    ...

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://a.a/1.0")]
public partial class ContextType {
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string Foo;
Run Code Online (Sandbox Code Playgroud)

我发现奇怪的事情:

  1. 在为此服务生成WSDL时,WSDL会将自己的名称空间添加到WSDL定义中(xmlns:b例如,在上面的示例中).
  2. WSDL不尊重unqualified代理中定义的注释,并使所有内容都合格.

我尝试了各种注释组合,但似乎没有任何帮助; 来自B的消息未正确反序列化为由A生成的代理.任何想法/指针/帮助将非常感谢!

tmb*_*gmn 5

在一个典型的"问问题,5分钟后自己解决"的情况下,我已经设法解决了我的问题.

问题是,显然,当使用WCF .NET时,对数据协定中涉及的类使用默认的序列化程序.这个默认的序列化程序(我相信它DataContractSerializer)显然并没有真正允许配置方式.我不得不告诉WCF使用XmlSerializer序列化消息.要做到这一点,我不得不将添加[XmlSerializerFormat()]注释服务合同接口(显然它意味着在操作的工作以及).例:

[ServiceContract(Namespace = "http://a.a/1.0")]
[XmlSerializerFormat()]
public interface IMyWebService
{
    [OperationContract()]
    void DoStuff(Set_Out message);
}
Run Code Online (Sandbox Code Playgroud)

添加 [XmlSerializerFormat()]注释后,WSDL发生了显着变化(正确的名称空间),并且消息被正确序列化.

论坛帖子让我走上正轨:http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/c7fede29-56c2-4ff3-bd02-48e3e0b2cec1/