C# Сериализовать класс в byte [], который не помечен как Serializable - PullRequest
1 голос
/ 03 августа 2020

У меня есть классы, подобные приведенным ниже, и , которые я не могу изменить , поскольку это классы, которым уже почти 20 лет, и они уже находятся в производстве и используются многими приложениями. Это поддерживается командой, и прежде чем я go обращусь к ним с просьбой внести изменения, которые, как мне кажется, будут большим изменением, мне нужно убедиться, что я изучил все варианты.

[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.Address' в сборке 'xxx.yyy.zzz, Version = 1.0.0.0, Culture = нейтральный, PublicKeyToken = null' не помечен как сериализуемый.

Может кто-нибудь, пожалуйста, скажите мне, как мы можем решить эту проблему, не делая Address as Serializable. Мне нужно преобразовать dto в байт []

Заранее спасибо.

ОБНОВЛЕНИЕ 1

Я попробовал то, что @Neil предложил в комментариях, и теперь мой начальная проблема решена (я полагаю), но у меня возникла новая проблема, поэтому я чувствую, что делаю неправильно.

Это то, что я делаю сейчас

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'.

1 Ответ

2 голосов
/ 03 августа 2020

Если вы привязаны к BinaryFormatter, функция, которую вы ищете, - «суррогаты»; это не маленький топи c, поэтому трудно привести краткий пример, но полное пошаговое руководство описано здесь ; по сути, суррогат - это настраиваемый тип, который используется внутри вместо типа, с которым он сталкивается, поэтому ваш настраиваемый тип может выполнять все необходимые дополнительные logi c.

Однако! В общем, BinaryFormatter следует считать устаревшим и устаревшим. Никто не забирает его у вас, и он будет продолжать работать (по крайней мере, на. NET Framework), но: если возможно, вам следует рассмотреть возможность поиска альтернативных вариантов. По некоторым причинам: см. Здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...