WCF 和 .NET 5.0:字节数组反序列化问题

Posted

技术标签:

【中文标题】WCF 和 .NET 5.0:字节数组反序列化问题【英文标题】:WCF and .NET 5.0: Issue with byte array deserialization 【发布时间】:2021-04-30 09:23:14 【问题描述】:

我正在尝试使用现有的 WCF 服务(基本绑定),并且遇到了一些与接收到的消息的反序列化相关的问题。让我从显示消息的 sn-p 开始:

<s:Body>
  <ObtemUtilizadoresResponse xmlns="http://xxx. pt/Mercados"><ObtemUtilizadoresResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
     <util>
       <Id>123</Id>
       <ver>AAAAAACL5j4=</ver>
       <im>-2</im>
       <n>User 123</n>
     </util>
   ....
</s:Body>

最初,我首先创建一个新的 DTO 来执行反序列化,如下所示:

[DataContract(Namespace = "http://xxx.pt/Mercados", Name = "util")]
public class Utilizador 
    [field: DataMember(Name = "Id")]
    public int Id  get; set; 
    
    [field: DataMember(Name = "ver")]
    private byte[] Version  get; set; 
    
    [field: DataMember(Name = "n")]
    public string Nome  get; set; 
   
    [field: DataMember(Name = "im")]
    public int IdMercado  get; set; 

即使创建了实例,它也只会填充IdVersion 属性。如果我删除 Version 属性,则剩余的属性将被填充。为了填充所有属性,我不得不将 Version 移动到基类:

[DataContract(Namespace = "http://xxx. pt/Mercados", Name = "vb")]
public class Base        
    [field: DataMember(Name = "ver")]
    private byte[] Version  get; set; 


[DataContract(Namespace = "http://xxx.pt/Mercados", Name = "util")]
public class Utilizador:Base 
... //removed Version property

有人知道为什么会这样吗?

谢谢。

【问题讨论】:

【参考方案1】:

经过一番挖掘,似乎有对这种行为的解释。当您使用DataContractSerializer 时,类型内的默认序列化顺序是按字母顺序排列的,如果您使用的是类层次结构,则顺序是自上而下的。如果序列化顺序不匹配,成员将被初始化为其默认值。这就是为什么当我引入基类时一切正常的原因(因为服务使用基类作为被序列化的类型)。

因此,如果您想在客户端扁平化层次结构,则需要使用DataMemberAttributeOrder 属性。您可以将正确的订单位置应用于每个属性(以便它模仿服务器上正在序列化的内容),或者您可以通过为属于层次结构每个级别的属性赋予相同的值来“分组”它们(并依赖于具有相同 order 值的属性的默认字母顺序 - 顺便说一句,它基于 Name 属性,如果您还设置它):

[DataContract(Namespace = "http://xxx.pt/Mercados", Name = "util")]
public class Utilizador 
    [field: DataMember(Name = "Id", Order = 1)]
    public int Id  get; set; 

    [field: DataMember(Name = "ver", Order = 1)]
    private byte[] Version  get; set; 

    [field: DataMember(Name = "n", Order = 2)]
    public string Nome  get; set; 

    [field: DataMember(Name = "im", Order = 2)]
    public int IdMercado  get; set; 

【讨论】:

以上是关于WCF 和 .NET 5.0:字节数组反序列化问题的主要内容,如果未能解决你的问题,请参考以下文章

Protobuf-net 对字节数组进行序列化/反序列化

使用JSON.Net反序列化包含字典的字节数组[重复]

在 C# 中为 WCF 服务反序列化简单的 XML 数组对象

护网面试题5.0

ProtoBuf 在反序列化期间损坏字节数组(添加了额外的 0)

WCF 服务已超出最大数组长度配额 (16384)