2017-06-28 18 views
1

私が実行してJSONへのルックアップをシリアル化しようとしている:Lookup <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);   

としてシリアル化:あなたは正しくキー名(ABC)が欠落している気づく

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

、配列の配列として直列化されるように見えます。

ルックアップをシリアル化するためのサポートがないように見えるので、独自のコンバータを作成する必要があります。

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"] 
} 

それを修正し、これは仕事をしていません

関連する問題