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 。 另一方面,每当我为a参数传递Code.TypeACode.TypeB ,服务总是正确地反序列化它。

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

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

对于这么基本的东西,这个问题似乎exception模糊。 我测试了从服务中传回Status.NotWorking并且客户端能够看到它,因此这似乎是一个单向问题。 有什么建议?

编辑1:

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

编辑2:

从缺乏立即反应来判断,我将包括一些更多的信息,以防其中一些情况发生。

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

枚举:

 ///  [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服务,但它不会重现我所看到的行为。 我的猜想是,其他一些代码正在zilching DataContractSerializer,或者有一些相关的IIS / WCF设置,或者一些未解决的数据合同问题。

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

编辑4

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

    TypeA  mystuffvalue     

因此,枚举永远不会被传递! 如何解决合同不匹配问题?

编辑5

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

关键在这里:

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

XML Serializer用于生成代理而不是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;} }