Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF服务未反序列化枚举值_C#_Wcf - Fatal编程技术网

C# 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

我构建了一个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
}
<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和自定义身份验证方案
  • Method
    上还有一个FaultContract属性,但为了简化示例,我排除了它
  • 事件查看器说是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不支持的。