我构建了一个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
}
Run Code Online (Sandbox Code Playgroud)
现在我将它用作C#客户端的服务参考.出于某种原因,每当我调用时Method
,参数MyStatus
内的属性b
总是设置为WorksFine
,即使我将其设置为NotWorking
.在另一方面,每当我经过Code.TypeA
或Code.TypeB
为a
参数,服务总是正确地反序列化.
尽职调查的目的,在经过对枚举WCF服务的主题其他职位是指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) { ... }
}
Run Code Online (Sandbox Code Playgroud)
对于这么基本的事情,这个问题似乎异常模糊.我测试了Status.NotWorking
从服务中传回来,客户端也可以看到它,所以这似乎是一个单向问题.有什么建议?
编辑1:
类似的问题:WCF没有反序列化值类型.神秘的行为
编辑2:
从缺乏立即反应来判断,我将包括一些更多信息,以防其中一些情况发生.
Method
但我将其排除在外以使示例更简单.枚举:
/// <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 }
Run Code Online (Sandbox Code Playgroud)
方法:
// 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);
Run Code Online (Sandbox Code Playgroud)
编辑3:
我构建了另一个只包含上面代码的Web服务,但它不会重现我所看到的行为.我的猜想是,其他一些代码正在zilching 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>
Run Code Online (Sandbox Code Playgroud)
因此,枚举永远不会被传递!如何解决合同不匹配问题?
编辑5
忘记提到Web服务引用了ASMX服务,并且本身使用XML序列化程序与该外部服务进行通信.
由于某种未知的原因,客户端发出的 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;}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3082 次 |
最近记录: |