C# WCF服务未反序列化枚举值
我构建了一个WCF服务,其中有一个部分如下所示:C# WCF服务未反序列化枚举值,c#,wcf,C#,Wcf,我构建了一个WCF服务,其中有一个部分如下所示: [ServiceContract] public class Service { [OperationContract] public SomethingElse[] Method(Code a, params Something[] b) { ... } } [DataContract] public class Something { [DataMember] public string Stuff {get
[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
}
<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>
现在,我将其用作C#client的服务参考。出于某种原因,无论何时调用方法
,b
参数中的MyStatus
属性总是设置为WorksFine
,即使我将其设置为NotWorking
。另一方面,每当我为a
参数传递code.TypeA
或code.TypeB
时,服务总是正确地反序列化它
为了尽职调查,关于向WCF服务传递Enum的其他帖子涉及到DataContract
,EnumMember(Value=“TypeA”)
,以及ServiceKnownType
,所以我尝试了所有这些。然而,即使我使用ServiceKnownType
(如下所示),我仍然会遇到同样的问题
[ServiceContract]
[ServiceKnownType(typeof(Something)]
[ServiceKnownType(typeof(Status)]
public class Service {
[OperationContract]
public SomethingElse[] Method(Code a, params Something[] b) { ... }
}
对于如此基本的东西来说,这个问题似乎异常模糊。我测试了从服务返回状态。NotWorking
,客户端也可以看到,因此这似乎是一个单向问题。有什么建议吗
编辑1:
类似问题:
编辑2:
从缺乏即时响应的情况来看,我将提供更多信息,以防其中一些出现问题
- 我在.NET 4.5和4.0上都遇到此问题
- 该服务托管在IIS上,具有SSL和自定义身份验证方案
上还有一个FaultContract属性,但为了简化示例,我排除了它Method
- 事件查看器说是Zlich。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 }
编辑3:
我构建了另一个web服务,它只包含上面的代码,但它没有重现我看到的行为。我的猜测是,要么其他一些代码正在处理DataContractSerializer,要么存在一些相关的IIS/WCF设置,要么存在一些未解决的数据契约问题
我还构建了另一个连接到两个web服务的web客户端,它收到的结果与第一个相同
编辑4
用Fiddler截获了请求,结果如下:
[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
}
<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>
A型
mystuffvalue
因此,枚举毕竟永远不会被传递!如何修复此合同不匹配
编辑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;}
}
您是否尝试过通过DataContractSerializer运行数据类以查看实际序列化的内容?您是否也尝试过完全从枚举中删除属性?我从未看过DataContractSerializer,也没有尝试从枚举中删除属性。我将尝试这两种方法。好的,现在我已经尝试使用
[OnDeserialization]
来查看某些东西正在反序列化时的状态。但是MyStatus
属性仍然默认为其默认值。是否有更有用的方法来查看反序列化?删除枚举上的属性也会导致无法传入所需的参数。请尝试使用BasicHttpBinding
,并使用Fiddler或类似工具在线路上捕获请求。发布后,修改请求格式,然后再次将其发送到服务。这很可能是合同不匹配类型的问题。这闻起来像asmx服务。你应该用服务推荐,我用过。然而,在web服务的实际实现中,web服务引用了ASMX web服务。也许它不知怎么泄露出去了?我看了你的另一篇文章。XmlElement属性强制.NET使用XML序列化程序。如果删除这些,枚举将开始工作。你在这里发布的是一个狡猾的变通方法。宾果。我刚刚查看了web服务中的ASMX web服务,在reference.cs中有各种各样的XmlElement属性。下次我不会忘记提到asmx引用:)如果公共契约不包含任何特定于xml序列化程序的指令,比如这些属性,那么我相当确定DataContractSerializer仍然可以使用。如果不是,则是配置问题,或者您的数据类型的结构是DataContractSerializer不支持的。