Только сериализовать некоторые определенные свойства класса?

У меня возникла проблема с Json.Net.

Мое приложение подключено к базе данных и хранит в ней некоторые данные. Предположим, что мое приложение имеет три разных класса: Entity, Group, Organization.

Краткий обзор класса Entity:

public class Entity
{
    [JsonIgnore]
    public int ID { get; private set; }
    [JsonProperty]
    public string UID { get; private set; }
    [JsonProperty]
    public Gender EntityGender { get; set; }
    [JsonProperty]
    public string Surname { get; set; }
    [JsonProperty]
    public string Forename { get; set; }
    [JsonProperty]
    public Group EntityGroup { get; set; }
    [JsonProperty]
    public Organisation EntityOrganisation { get; set; }

Организация и группа также имеют свойство ID.
При сериализации объекта я не хочу полностью сериализовать EntityGroup и EntityOrganisation, а только их идентификаторы.

Небольшой пример того, как я хотел бы, чтобы это выглядело:

(Как это выглядит сейчас)

{
  "UID": "6c5204356b3a1a33",
  "Surname": "Bar",
  "Forename": "Foo",
  "EntityGroup": {
    "Name": "XGroup",
    "GroupOrganisation": {
      "Name": "FooOrg"
    }
  },
  "EntityOrganisation": null,
  "EntityStation": null
}

(Как это должно выглядеть)

{
  "UID": "6c5204356b3a1a33",
  "Surname": "Bar",
  "Forename": "Foo",
  "EntityGroup": {
    "ID": 1,
    "GroupOrganisation": {
      "ID": 1
    }
  },
  "EntityOrganisation": null,
  "EntityStation": null
}

Можно ли настроить JsonParser, который сериализует только свойство ID группы и организации при сериализации объекта?


person TorbenJ    schedule 01.12.2012    source источник
comment
Что вы хотите, чтобы произошло с организацией и группой при десериализации?   -  person tallseth    schedule 01.12.2012
comment
Я не буду десериализовать его напрямую. Я проанализирую его и загружу соответствующую организацию/группу из базы данных. Может быть, я сделаю это по-другому, но это моя текущая идея :)   -  person TorbenJ    schedule 01.12.2012
comment
Или, может быть, я могу использовать решение nick_w, чтобы просто загрузить организацию/группу при десериализации.   -  person TorbenJ    schedule 01.12.2012


Ответы (1)


Как насчет этого:

В своем классе Entity добавьте атрибут JsonConverter к классу EntityGroup:

[JsonProperty]
[JsonConverter(typeof(EntityGroupConverter))]
public Group EntityGroup { get; set; }

Это будет использовать EntityGroupConverter для сериализации Group. Этот класс выглядит следующим образом:

class EntityGroupConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Group);
    }

    public override object ReadJson(JsonReader reader, Type objectType,
        JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value,
        JsonSerializer serializer)
    {
        Group group = value as Group;
        serializer.Serialize(writer, new { ID = group.ID,
            GroupOrganisation = new { ID = group.Organisation.ID } });
    }
}

Ключевым моментом здесь является использование serializer для записи анонимного объекта, который включает только нужные свойства.

Обратите внимание, что ReadJson остался нереализованным — я предполагаю, что на данном этапе десериализация не требуется.

Изменить

Как указал Скадьер, подпись ReadJson будет выглядеть так в более поздних версиях Json.NET (в этом вопросе используется версия 3.5.0.0):

public override object ReadJson(JsonReader reader, Type objectType,
        object existingValue, JsonSerializer serializer)
person nick_w    schedule 01.12.2012
comment
Спасибо, это работает! :) Мне просто нужно было исправить ваш метод ReadJson(), потому что параметры были неправильными. - person TorbenJ; 01.12.2012
comment
@Skadier Рад, что это сработало для вас! Я отредактировал свой ответ, чтобы упомянуть вашу точку зрения о параметрах ReadJson. - person nick_w; 01.12.2012