2017-06-28 46 views
1

我試圖做序列化到查找JSON:如何將查找<string,string>對象序列化爲JSON?

Lookup<string, string> productIdsByCategory = prodcuts.ToLookup(p => p.Category, p => p.Id); 

然後在我的ASP.NET核心的WebAPI控制器我要回做:

var response = new ComplexType 
{ 
    PropertyA = productIdsByCategory 
    ... other properties left out ... 
}; 
return Json(response) 

從郵差的響應我的WebAPI看起來像這樣:

{ 
    "PropertyA": [ 
    [ 
     "ProductId_A" 
    ], 
    [ 
     "ProductId_B" 
    ], 
    [ 
     "ProductId_C" 
    ] 
    ], 
    ... other properties left out ... 
} 

鍵不包含在JSON響應中,它甚至可以這樣做嗎?

回答

2

你說得對,因爲Newtonsoft.Json不會很好地對待Lookup<TKey, TElement>。下面的代碼:

var input = new List<string>() 
{ 
    "A1", 
    "A2", 
    "B1", 
    "C1", 
    "C2" 
}; 

var lookup = input.ToLookup(i => i[0], i => i); 
var json = JsonConvert.SerializeObject(lookup); 

Console.WriteLine(json);   

序列化爲:

[["A1","A2"],["B1"],["C1","C2"]] 

你正確地注意到(ABC)缺少關鍵的名稱,它似乎被序列化爲一個數組的數組。

似乎不支持序列化外觀查找,所以你必須編寫自己的轉換器。

我找到了一個here,但這要求您事先知道密鑰類型和值。

修改它,這樣做的工作:

 // Same as above, up till here 
     var json = JsonConvert.SerializeObject(lookup, new LookupSerializer()); 
     Console.WriteLine(json); 
    } 
} 

public class LookupSerializer : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     var result = objectType.GetInterfaces().Any(a => a.IsGenericType 
      && a.GetGenericTypeDefinition() == typeof(ILookup<,>)); 
     return result; 
    } 

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

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var obj = new JObject();    
     var enumerable = (IEnumerable)value; 

     foreach (object kvp in enumerable) 
     { 
      // TODO: caching 
      var keyProp = kvp.GetType().GetProperty("Key"); 
      var keyValue = keyProp.GetValue(kvp, null); 

      obj.Add(keyValue.ToString(), JArray.FromObject((IEnumerable)kvp)); 
     } 

     obj.WriteTo(writer); 
    } 
} 

輸出:

{ 
    "A": ["A1", "A2"], 
    "B": ["B1"], 
    "C": ["C1", "C2"] 
} 
相關問題