2017-04-13 64 views
1

我有一個嵌套的對象打開特定對象字段轉換爲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

回答

2

我會使用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

0

鑑於我不能修改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