Объект JSON Serialization Proprty в списке ключей и значений
Я изо всех сил пытаюсь изменить один список в форме ключа и значения.
Как пример: у меня есть объект списка свойств
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 ответ
Начнем с того, что данный выходной пример не совсем корректный 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 в ключ "Подробности", как в 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"
}
]
}