json - 如何将Lookup <string,string>对象序列化为JSON?

标签 json asp.net-web-api serialization

我正在尝试通过执行以下操作将Lookup序列化为JSON:

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

然后在我的ASP.NET Core WebAPI Controller 中,我通过执行以下操作返回:
var response = new ComplexType
{
     PropertyA = productIdsByCategory
     ... other properties left out ...
};
return Json(response)

我的WebAPI在Postman中的响应如下所示:
{
  "PropertyA": [
    [
      "ProductId_A"
    ],
    [
      "ProductId_B"
    ],
    [
      "ProductId_C"
    ]
  ],
  ... other properties left out ...
}

key 不包含在JSON响应中,甚至可以这样做吗?

最佳答案

您在那个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"]
}

关于json - 如何将Lookup <string,string>对象序列化为JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44802643/

相关文章:

json - hive 中的JSON解析问题

json - 需要从包含特定字符 '/' 的 JSON 中获取所有键值对

c# - ASP.NET Web API 跨请求缓存操作过滤器属性

java - 需要在不编写包装器的情况下使第三方对象可序列化

c# - 使用 C# 调用 json

JSON作为数据传输的媒介

c# - 没有内容的 POST 请求通过模型验证

c# - 如何在 C# 应用程序中使用 FluentValidation

java - 使用 XMLEncoder 序列化 UUID

java - CRUD架构设计-反序列化