Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何序列化查找<;字符串,字符串>;对象转换为JSON?_Json_Asp.net Web Api_Serialization - Fatal编程技术网

如何序列化查找<;字符串,字符串>;对象转换为JSON?

如何序列化查找<;字符串,字符串>;对象转换为JSON?,json,asp.net-web-api,serialization,Json,Asp.net Web Api,Serialization,我正在尝试通过执行以下操作将查找序列化为JSON: Lookup<string, string> productIdsByCategory = prodcuts.ToLookup(p => p.Category, p => p.Id); var response = new ComplexType { PropertyA = productIdsByCategory ... other properties left out ... }; retur

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

Lookup<string, string> productIdsByCategory = prodcuts.ToLookup(p => p.Category, p => p.Id);
var response = new ComplexType
{
     PropertyA = productIdsByCategory
     ... other properties left out ...
};
return Json(response)
my WebAPI在Postman中的响应如下所示:

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

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

你说得对,Newtonsoft.JSON不能很好地处理
查找。以下代码:

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);        
您正确地注意到缺少键名(
A
B
C
),它似乎被序列化为数组数组

似乎不支持序列化开箱即用的查找,因此您必须编写自己的转换器

我找到了一个,但这需要您事先知道密钥的类型和值

修改后,这将完成以下工作:

        // 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);
    }
}

作为创建自定义转换器的变通方法,您可以将
查找
转换为
字典
,Newtonsoft.Json可以很好地使用它

myLookup.ToDictionary(x => x.Key, x => x.ToList());

这是一个很好的解决方法。不幸的是,由于Dictionary对象所涉及的哈希代码计算,它没有那么有效。答案很好。如果有人(如我)正在使用序列化时要使用的自定义设置,则可以将
序列化程序
参数添加到序列化IEnumerable的行中<代码>obj.Add(keyValue.ToString(),JArray.FromObject((IEnumerable)kvp,**序列化程序**)
{
    "A": ["A1", "A2"],
    "B": ["B1"],
    "C": ["C1", "C2"]
}
myLookup.ToDictionary(x => x.Key, x => x.ToList());