C# .NET WCF序列化问题

C# .NET WCF序列化问题,c#,.net,wcf,xml-serialization,C#,.net,Wcf,Xml Serialization,情况:系统A应该公开SOAP1.2Web服务,以便系统B调用。为了让A知道消息的外观,B向A发送了一个XSD,描述消息的内容。A使用.NET xsd.exe工具生成存根,围绕此创建简单的Web服务,并完成了工作 但是,;当B调用此webservice时,A拒绝将SOAP/XML内容序列化到生成的代理类实例。我意识到这一定是因为序列化是在系统A的webservice端定义的,但一直无法准确定位出哪里出了问题 来自B的消息看起来像什么(匿名)-失败: <ns2:Set_Out xmlns:ns

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

但是,;当B调用此webservice时,A拒绝将SOAP/XML内容序列化到生成的代理类实例。我意识到这一定是因为序列化是在系统A的webservice端定义的,但一直无法准确定位出哪里出了问题

来自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>
<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>
[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;
我觉得奇怪的是:

  • 为该服务生成WSDL时,WSDL将自己的名称空间添加到WSDL定义中(例如,在上面的示例中,
    xmlns:b
  • WSDL不尊重代理中定义的
    非限定的
    注释,并使所有内容都限定
  • 我尝试了各种注释组合,但似乎没有任何帮助;来自B的消息未正确反序列化到A生成的代理。任何想法/指针/帮助都将不胜感激

    (这实际上是一条评论,但不合适)

    尝试将system.diagnostics添加到web.config以了解有关错误的更多信息:

        <system.diagnostics>
        <trace autoflush="true" />
        <sources>
            <source name="System.ServiceModel"
                    switchValue="Information, ActivityTracing"
                    propagateActivity="true">
                <listeners>
                    <add name="sdt"
                        type="System.Diagnostics.XmlWriterTraceListener"
                        initializeData= "C:\MyLog.svclog" />
                </listeners>
            </source>
        </sources>
        </system.diagnostics>
    
    
    
    您可以使用
    C:\Program Files\Microsoft SDK\Windows\v6.0A\bin\SvcTraceViewer.exe
    (或类似工具)查看svclog。将其添加到两个服务中(当然是不同的日志文件名),然后查看哪个服务失败,以及具体原因

    我怀疑序列化是正常的,但服务的某些绑定/设置会导致调用失败。

    在典型的“提问,5分钟后自己解决”的情况下,我已经设法解决了我的问题

    问题是,显然,在使用WCF.NET时,会对数据协定中涉及的类使用默认序列化程序。这个默认的序列化程序(我相信它是
    DataContractSerializer
    )显然在配置方面不允许太多。我不得不告诉WCF使用
    XmlSerializer
    来序列化消息。要做到这一点,我必须将
    [XmlSerializerFormat()]
    注释添加到服务契约接口(显然它也用于操作)。例如:

    [ServiceContract(Namespace = "http://a.a/1.0")]
    [XmlSerializerFormat()]
    public interface IMyWebService
    {
        [OperationContract()]
        void DoStuff(Set_Out message);
    }
    
    添加
    [XmlSerializerFormat()]
    注释后,WSDL发生了显著变化(正确的名称空间),消息被正确序列化


    让我走上正轨的论坛帖子:

    注意:上面的XML示例是整个消息的摘录,显然这包含了更多与SOAP相关的内容,但为了简洁起见,我将其省略了。为什么要发送XSD?为什么不直接使用“添加服务参考”?我有同样的反应,但我在为一家公司咨询,而这家公司在我的故事中是系统B,所以我避免了冲突,并按照它去做。事实上,这是一种相反的工作方式;我没有让客户机遵守契约(WSDL),而是侵入契约使客户机工作。有人可能会说这很愚蠢,而且是“做错了”。@pHk:我会说这是无法维护的,不符合标准,而且违背了客户的长期利益。好吧,很典型,但我认为我找到了一个似乎可行的解决方案,需要做更多的测试,BRB:)