【问题标题】:C# Serialize class into byte[] that is not marked as SerializableC#将类序列化为未标记为可序列化的字节[]
【发布时间】:2020-08-03 19:02:59
【问题描述】:

我有像下面这样的类,我无法改变,因为这些类已经有将近 20 年的历史了,而且它们已经在生产中被许多应用程序使用。 这是由一个团队维护的,在我去找他们并要求做出我认为会是很大的改变之前,我需要确保我探索所有选项。

[Serializable]
public class MyDTO
{
  public string FullName {get;set;}
  public List<Address> Addresses {get;set}
}

// Note: It is not marked as Serializable
public class Address
{
  public string FullAddress {get;set;}
  
}

我正在创建如下所示的 MyDTO

List<Address> myAddresses = new List<Address>()
{
   new Address() { FullAddress =" FullAddress1"},
   new Address() { FullAddress =" FullAddress2"}
}

MyDTO dto = new MyDTO() 
{
  FullName = "FullName",
  Addresses = myAddresses
}

现在我正在尝试将 dto 转换为 byte[],如下所示。

public byte[] SerializeToByteArray(MyDTO dto)
{
  byte[] byteArray = null;
  BinaryFormatter bf = new BinaryFormatter();
  using (MemoryStream ms = new MemoryStream())
  {
    bf.Serialize(ms, dto);
    byteArray = ms.ToArray();
  }
  return byteArray;
}

我得到了例外 在程序集 'xxx.yyy.zzz, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 中键入 'xxx.Address' 未标记为可序列化。

谁能告诉我如何在不将地址设置为可序列化的情况下解决此问题。 我需要将 dto 转换为 byte[]

提前致谢。

更新 1

我尝试了@Neil 在 cmets 中的建议,现在我最初的问题已解决(我假设)但我遇到了新问题,所以我觉得我做错了。

这就是我现在正在做的事情

public byte[] SerializeToByteArray<T>(T dto)
{
 byte[] byteArray = null;
 BinaryFormatter bf = new BinaryFormatter();
 using (MemoryStream ms = new MemoryStream())
 {
   bf.Serialize(ms, dto);
   byteArray = ms.ToArray()
 }
 return byteArray;
}
string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(dto);
byte[] byteArray = SerializeToByteArray(jsonString);
string dtoByteArrayBase64String = Convert.ToBase64String(byteArray);

我将 dtoByteArrayBase64String 发送到服务器端,我正在接收它。 在服务器上,我尝试重新创建 MyDTO 对象,如下所示

byte[] inputDTOByteArray = Convert.FromBase64String(dtoByteArrayBase64String);
MyDTO  myDTO = DeserializeFromByteArray<MyDTO>(inputDTOByteArray);

public T DeserializeFromByteArray<T>(byte[] byteArray)
{
  T dto;
  BinaryFormatter bf = new BinaryFormatter();
  using (MemoryStream ms = new MemoryStream(byteArray))
  {
    object obj = bf.Deserialize(ms);
    dto = (T)obj; // getting error here
  }
  return dto;
}

我遇到以下错误 无法将“System.String”类型的对象转换为“MyDTO”类型。

【问题讨论】:

  • 问题:你限制BinaryFormatter;还有其他序列化程序可能可以在这里工作,但是如果您真的是指“使用BinaryFormatter”,那不值得讨论;如果您的意思是“与BinaryFormatter”,我能想到的唯一选择是“代理”
  • @MarcGravell... SerializeToByteArray 是我的方法,我可以使用任何格式化程序,除非我得到安全团队的审查并且它有效。你所说的代理是什么意思?
  • 这里是代理的演练 - 它几乎完全适用于这种情况:riptutorial.com/csharp/example/14386/… - 至于其他序列化程序:我有偏见,所以我在考虑 protobuf-net :)跨度>
  • 能不能先序列化成json再序列化成byte[]?
  • @MarcGravell.. 我会调查的...

标签: c# serialization binary-serialization


【解决方案1】:

如果您与BinaryFormatter 绑定,您正在寻找的功能是“代理”;这不是一个小话题,所以很难给出一个简洁的例子,但完整的演练已经涵盖了here;本质上,代理是一种在内部使用的自定义类型而不是它遇到的类型,因此您的自定义类型可以执行所需的所有额外逻辑。

但是!一般来说,BinaryFormatter 应该被认为是遗留的和过时的。没有人会从您手中夺走它,它会继续工作(至少在 .NET Framework 上),但是:如果可能,您应该考虑寻找替代选项。部分原因:see here

【讨论】:

    猜你喜欢
    • 2015-02-15
    • 2019-12-15
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 2015-11-10
    • 2016-01-18
    • 2011-01-17
    相关资源
    最近更新 更多