打开特定对象字段转换为JSON

问题描述:

我有一个嵌套的对象打开特定对象字段转换为JSON

public class CardListViewModel 
{ 

    public virtual Guid Id { get; set; } 


    public virtual IEnumerable<Card> CardList { get; set; } 

} 

public class Card 
{  
    public virtual Guid Id { get; set; } 

    public virtual string IndexName { get; set; } 

    public virtual Image CardImage { get; set; } 
} 

public class Image 
{ 
//... 
public virtual string Src { get; set; } 
//... 
} 

所以卡可能

CardListViewModel.CardList[0] = {Id:5678, IndexName:"Visa", {Src:"Visa.png"}} 
CardListViewModel.CardList[1] = {Id:5555, IndexName:"MasterCard", {Src:"MasterCard.png"}} 

我要的结果是类似下面的

{ 
    "Visa": "Visa.png", 
    "MasterCard": "MasterCard.png" 
} 

一个JSON对象我无法修改POCO,我只需要列表中每个卡片的JSON片段及其相应的图像。当然,我可以用StringBuilder和循环蛮力,但我想知道是否有办法用JsonConvert库或任何其他处理映射的好工具来完成此操作?

+0

'Card.Id'会发生什么?它简单地被省略了吗?你可以分享你想要的JSON作为根CardListViewModel而不是仅仅与CardList相关的片段吗? – dbc

+0

所以我不能修改POCO,我想要的只是列表中每个卡片的Json片段及其对应的图像。 – Mike

我会使用LINQ来映射它和NewtonsoftJson来构建JSON。

using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 
using System.Linq; 

var mappedCards = JsonConvert.SerializeObject(new JObject (
    from card in CardListViewModel.CardList 
    select new JProperty(card.IndexName, card.CardImage.Src))); 
+0

谢谢你是我不知道的JProperty – Mike

鉴于我不能修改POCO和你正在寻找使用,您可以创建IEnumerable<Card>类型的对象custom JsonConverter如下:

using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 
using Newtonsoft.Json.Converters; 
using Newtonsoft.Json.Serialization; 

public class CardListConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(IEnumerable<Card>).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 
     var list = existingValue as ICollection<Card> ?? new List<Card>(); 
     var obj = JObject.Load(reader); 
     foreach (var property in obj.Properties()) 
     { 
      list.Add(new Card { IndexName = property.Name, CardImage = new Image { Src = (string)property.Value } }); 
     } 
     return list; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var collection = (IEnumerable<Card>)value; 
     writer.WriteStartObject(); 
     foreach (var item in collection) 
     { 
      writer.WritePropertyName(item.IndexName); 
      writer.WriteValue(item.CardImage == null ? null : item.CardImage.Src); 
     } 
     writer.WriteEndObject(); 
    } 
} 

然后用它序列化设置如下:

var settings = new JsonSerializerSettings 
{ 
    Converters = { new CardListConverter() }, 
}; 
var json = JsonConvert.SerializeObject(CardListViewModel, Formatting.Indented, settings); 

而你的CardListViewModel将是序列如下:

{ 
    "Id": "c2a7cc0f-0e6b-40a0-9020-aeba436265d4", 
    "CardList": { 
    "Visa": "Visa.png", 
    "MasterCard": "MasterCard.png" 
    } 
} 

样品fiddle