Упростить объект при сериализации JSON - PullRequest
0 голосов
/ 03 июня 2019

Учитывая следующие 2 класса (отредактировано для краткости), я создаю список вопросов. Каждому вопросу присваивается «учетная запись пользователя».

Затем я хочу сериализовать список вопросов, но для каждого UserAccount я хочу только написать свойство 'Id' (исключая любые другие свойства объекта UserAccount).

Я думаю, что для этого мне нужен специальный конвертер, но я не уверен, как перехватить любое вхождение свойства UserAccount и только сериализовать для него свойство Id.

public class Question
{
    public int Id { get; set; }
    public string Ask { get; set; }
    public UserAccount CreatedBy { get; set; }
}

public class UserAccount
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

Вот как в идеале должен выглядеть получившийся JSON:

[
   {
      "Id":1,
      "Ask":"Question 1",
      "CreatedBy":{
         "Id":1
      }
   },
   {
      "Id":2,
      "Ask":"Question 2",
      "CreatedBy":{
         "Id":1
      }
   },
   {
      "Id":3,
      "Ask":"Question 3",
      "CreatedBy":{
         "Id":1
      }
   }
]

Я не хочу использовать атрибуты Ignore для класса UserAccount, так как в некоторых других бизнес-случаях мне может потребоваться сериализация всех атрибутов. На самом деле я не хочу изменять ни класс Question, ни класс UserAccount.

Ответы [ 3 ]

1 голос
/ 03 июня 2019

Вы хотите игнорировать другие свойства условно .Чтобы достичь этого, используя NewtonJson, вы можете просто добавить метод в свой класс рядом со свойствами, которые имеют следующую подпись ( bool ShouldSerialize [PropertyName] ), см. Официальную документацию для получения дополнительной информации.детали.

Таким образом, ваш код будет выглядеть следующим образом

public class UserAccount
{
    // This will be serialized
    public int Id { get; set; }

    // This may (or may not) be be serialized depending on your condition
    public string Name { get; set; }
    // This also may (or may not) be be serialized depending on your condition
    public string Email { get; set; }

    public bool ShouldSerializeName()
    {
        if(someCondition)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public bool ShouldSerializeEmail()
    {
        if(someCondition)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

Если вы не хотите редактировать исходные классы, вы можете, например, заключить их в другой класс (или наследовать от них)), и используйте класс derrived.Таким образом, вы просто наследуете свойства и добавляете методы в класс derrived.Это может быть одним из возможных решений (я не уверен, что вы могли бы найти лучшее решение).

0 голосов
/ 03 июня 2019

Вы можете создать пользовательский JsonConverter для ваших требований и в методе «WriteJson» вы можете попробовать следующую реализацию:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    JToken t = JToken.FromObject(value);

    if (t.Type != JTokenType.Object)
    {
        t.WriteTo(writer);
    }
    else
    {
        JObject o = (JObject)t;
        var property = o.Properties().FirstOrDefault(p => p.Name == "CreatedBy");
        if(property != null)
        {
            o.Remove(property.Name);
            var newObj = new JObject();
            newObj.Add(new JProperty("Id",((JObject)property.Value).Properties().First(p => p.Name == "Id").Value));
            var newProperty = new JProperty(property.Name, newObj);
            o.Add(newProperty);
            o.WriteTo(writer);
        }
    }
}

И код сериализации будет выглядеть так:

var json = JsonConvert.SerializeObject(questions,  // your list of 'Question'
                                       Newtonsoft.Json.Formatting.Indented, 
                                       new MyCustomJsonConverter(typeof(Question)));
0 голосов
/ 03 июня 2019

если вы используете NewtonSoft, для этого необходимо добавить атрибут «JsonIgnore» в реквизит (или «DataContract» в класс и «DataMember» в реквизит) или реализовать IContractResolver

https://www.newtonsoft.com/json/help/html/ReducingSerializedJSONSize.htm

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