C # Json Интерфейс сериализации parent-child - PullRequest
0 голосов
/ 21 января 2019

это может быть легкое / быстрое решение, но из моего расследования мне не удалось его найти.

   public interface IBaseMessage
   {

   }

   public interface IRefreshMessage : IBaseMessage
   {

   }

Оба реализуются конкретными классами в библиотеке. Сообщение

Они хранятся внутри List<IBaseMessage>, и когда я сериализую объект для отправки по сети (один за другим), он помечается как IBaseMessage, даже если некоторые из них IRefrehMessage

Проблема: при десериализации (на другом ПК) они восстанавливаются как IBaseMessage, и вся информация из IRefreshMessage теряется.

Предположение: я полагаю, что должен быть какой-то атрибут класса JSON, который позволяет мне указывать, что должно быть сериализовано?

Спасибо и простите за довольно глупый вопрос

Edit:

Использование этого класса для сериализации / десериализации:

using Newtonsoft.Json.Linq;
public class JMessage
{
   public Type Type { get; set; }
   public JToken Value { get; set; }

   public static JMessage FromValue<T>(T value)
   {
       return new JMessage { Type = typeof(T), Value = JToken.FromObject(value) };
   }

   public static string Serialize(JMessage message)
   {
      return JToken.FromObject(message).ToString();
   }

   public static JMessage Deserialize(string data)
   {
      return JToken.Parse(data).ToObject<JMessage>();
   }  

Один раз звонит

string data = JMessage.Serialize(JMessage.FromValue(message));

Я получаю:

{
  "Type": "Universal_Tool_Manager.Messages.Message.Interfaces.IBaseMessage, Universal Tool Manager.Messages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
  "Value": {
    "Propagation": 2,
    "State": 0
  }
}

Надеюсь, это поможет.

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Я задал неправильный вопрос здесь:)

   public static JMessage FromValue<T>(T value)
    {
        return new JMessage { Type = **typeof(T)**, Value = JToken.FromObject(value) };
    }

Проблема была в typeof (T), который, конечно, всегда будет возвращать базовый интерфейс IBaseInterface, так как я использую

List<IBaseInterface>, 

Решением было использование value.GetType (),

извините за ошибку новичка

0 голосов
/ 21 января 2019

JSON.NET позволяет вам указать, как обрабатывать сериализацию и десериализацию, используя JsonSerializerSettings:

class Program
{
    static void Main(string[] args)
    {
        var items = new List<Test>
        {
            new Test() {Hello = "Hi"},
            new TestDerived() {Hello = "hello", Second = "World"}
        };
        var settings = new JsonSerializerSettings() 
        {
             TypeNameHandling = TypeNameHandling.Objects
        };
        var text = JsonConvert.SerializeObject(items, settings);
        var data = JsonConvert.DeserializeObject<IEnumerable<Test>>(text, settings);
    }
}

public class Test
{
    public string Hello { get; set; }
}

public class TestDerived : Test
{
    public string Second { get; set; }
}

В этом примере сгенерированный JSON будет содержать имя фактического типа, который был сериализован, и JSON.NET будет использовать эту информацию для десериализации обратно до правильного производного типа - data[1] равно TestDerived в моем примере кода.

Чтобы использовать JsonSerializerSettings с FromObject и Parse методами, вам необходимо создать экземпляр JsonSerializer:

var serializer = sonSerializer.Create(settings);
JToken.FromObject(o, serializer)
//and
JToken.Parse(data).ToObject<JMessage>(serializer);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...