Объект JSON Serialization Proprty в списке ключей и значений - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь изменить один список в форме ключа и значения.

В качестве примера: у меня есть объект свойства списка

public List<Details> Details{get;set;}
public class Details
{
 public string FirstName{get;set;}
 public string LastName{get;set;}
}

Я ищу JSONстрока с использованием этого объекта в следующем формате:

{"Details":[
{"Key":"FirstName" ,"Value":"value in list object"},
{"Key":"LastName" ,"Value":"value in list object"}
]}

Я не могу добиться этого с помощью сериализации JSON.Есть ли способ добиться этого с помощью любого доступного сериализации?

Спасибо, ребята, заранее.

1 Ответ

0 голосов
/ 15 февраля 2019

Начнем с того, что приведенный пример выходных данных не совсем корректный Json, так как на обоих концах отсутствуют "{" и "}".

Вы можете добиться указанного выше формата, используя Custom Json Converter ианонимный тип упаковки перед сериализацией.Например,

Рассмотрим следующий JsonConverter.

public class KeysJsonConverter : JsonConverter
{
    private readonly Type[] _types;

    public KeysJsonConverter(params Type[] types)
    {
        _types = types;
    }

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

        if(token.Type == JTokenType.Object)
        {
            JObject oldValue = (JObject)token;
            JObject newValue = new JObject();
            var jkey = oldValue.Properties().Select(x=>x.Name).First();
            var jvalue = oldValue.Properties().Select(x=>x.Value).First();

            newValue.AddFirst(new JProperty("Key",jkey));
            newValue.Add(new JProperty("Value",jvalue));
            newValue.WriteTo(writer);

        }
        return;

    }

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

    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return _types.Any(t => t == objectType);
    }
}

Теперь вы можете сериализовать коллекцию, используя следующее.

var result = JsonConvert.SerializeObject(details, 
                   Newtonsoft.Json.Formatting.Indented, 
                   new KeysJsonConverter(typeof(Details)));

Это приведет к следующему выводу.

[
  {
    "Key": "FirstName",
    "Value": "Anu"
  },
  {
    "Key": "FirstName",
    "Value": "Jia"
  }
]

Чтобы обернуть Json клавишей «Details», как в OP, вы можете обернуть свою коллекцию в анонимный тип.Например,

var result = JsonConvert.SerializeObject(new {Details=details}, 
                             Newtonsoft.Json.Formatting.Indented, 
                             new KeysJsonConverter(typeof(Details)));

Выходная выборка,

{
  "Details": [
    {
      "Key": "FirstName",
      "Value": "Anu"
    },
    {
      "Key": "FirstName",
      "Value": "Jia"
    }
  ]
}
...