枚举值不被WCF服务反序列化

我构建了一个WCF服务,并且有一个如下所示的部分:

[ServiceContract]
public class Service {
    [OperationContract]
    public SomethingElse[] Method(Code a, params Something[] b) { ... }
}

[DataContract]
public class Something {
    [DataMember]
    public string Stuff {get;set;}
    [DataMember]
    public Status MyStatus {get;set;}
    public string ServerSideField {get;set;}
}

[DataContract]
public class SomethingElse {
    [DataMember]
    public Status MyStatus {get;set;}
}

[DataContract]
public enum Status {
    [EnumMember] WorksFine,
    [EnumMember] NotWorking
}

[DataContract]
public enum Code {
    [EnumMember] TypeA,
    [EnumMember] TypeB
}

现在我将它用作C#客户机的服务参考。 出于某种原因,无论何时调用Method ,即使将其设置为WorksFineb参数中的MyStatus属性也始终设置为NotWorking 。 在另一方面,每当我经过Code.TypeACode.TypeBa参数,服务总是正确地反序列化。

为了尽职调查,关于将枚举传递给WCF服务的其他帖子引用DataContractEnumMember(Value="TypeA")ServiceKnownType所以我给了所有这些。 但是,即使当我使用ServiceKnownType (如下所示)时,我仍遇到同样的问题。

[ServiceContract]
[ServiceKnownType(typeof(Something)]
[ServiceKnownType(typeof(Status)]
public class Service {
    [OperationContract]
    public SomethingElse[] Method(Code a, params Something[] b) { ... }
}

这个问题似乎对于如此基本的东西来说非常模糊。 我测试了从服务传回的Status.NotWorking ,客户端也能够看到它,所以这似乎是一个单向问题。 有什么建议么?

编辑1:

类似的问题:WCF不反序列化值类型。 神秘的行为

编辑2:

从缺乏即时反应的角度来看,我将会收集一些更多的信息,以防其中的一些问题持续存在。

  • 我在.NET 4.5和4.0上遇到这个问题。
  • 该服务托管在IIS上,具有SSL和自定义身份验证方案。
  • Method上还有一个FaultContract属性,但为了使示例更简单,我排除了它。
  • 事件查看器说zilch。 IIS日志也是如此。
  • Reference.cs中的自动生成的服务参考代码如下所示:
  • 枚举:

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18408")]
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.datacontract.org/2004/07/Service")]
    public enum Status{ TypeA, TypeB }
    

    方法:

    // CODEGEN: Parameter 'MethodResult' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlArrayAttribute'.
        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/Service/Method", ReplyAction="http://tempuri.org/Service/MethodResponse")]
        [System.ServiceModel.FaultContractAttribute(typeof(MyClientProject.Service.MyFault), Action="http://tempuri.org/Service/MethodMyFaultFault", Name="MyFault", Namespace="http://schemas.datacontract.org/2004/07/Service.MyFault")]
        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
        MyClientProject.Service.Method Method(MyClientProject.Service.MethodRequest request);
    

    编辑3:

    我构建了另一个仅包含上述代码的Web服务,但它不能重现我所看到的行为。 我的猜想是,要么其他代码是过度DataContractSerializer,或者有一些相关的IIS / WCF设置,或者一些未解决的数据合同问题。

    我还构建了另一个连接到这两个Web服务的Web客户端,并且它获得了与第一个相同的结果。

    编辑4

    截取与Fiddler的请求,它看起来像这样:

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Method xmlns="http://tempuri.org/">
    <a>TypeA</a>
    <b><Something xmlns="http://schemas.datacontract.org/2004/07/TestService.Something">
       <Stuff>mystuffvalue</Stuff>
    </Something></b>
    </Method>
    </s:Body>
    </s:Envelope>
    

    所以枚举永远不会被传递! 我如何解决这个合同不匹配?

    编辑5

    忘了提及Web服务引用了ASMX服务,并且本身使用XML序列化程序与该外部服务进行通信。


    关键在于:

    [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]

    XML序列化程序正被用于生成代理而不是DataContractSerializer。 你无意中指定了XmlSerializer吗? 您是否尝试使用.asmx服务?

    一旦你找出了使用XmlSerializer生成代码的原因,你会得到你的答案,但是从你发布的内容来看,这并不是立即显而易见的。


    由于某些未知原因,客户端发出的SOAP请求忽略了我需要的枚举值,因此服务器将这些枚举序列化为其默认值(列表中的第一个枚举定义)。

    我通过使请求主体所需的省略参数解决了这个问题。 这是修复它的代码:

    [DataContract]
    public class Something {
        [DataMember]
        public string Stuff {get;set;}
        [DataMember(IsRequired=true)] // just this 1 simple change!
        public Status MyStatus {get;set;}
        public string ServerSideField {get;set;}
    }
    
    链接地址: http://www.djcxy.com/p/83411.html

    上一篇: Enum Value Is Not Deserialized By WCF Service

    下一篇: What is a viable method of spacing out text in visual studio