如何反序列化 JSON 到 IList<KeyValuePair<string, object>> 键中有空格?

How to deserialize JSON to IList<KeyValuePair<string, object>> with whitespaces in key?

我在将 JSON 反序列化为一个对象时遇到了一个大问题。它应该被反序列化为 IList<KeyValuePair<string, object>> 问题是键有空格。

"spec": {
         "SOMETHING WITH SPACES" : "10"
         etc. 
         ...
}
public class SomeObject
{
...
public IList<KeyValuePair<string, object>> spec{ get; set; }
...
}

反序列化代码:

var sr = new ServiceStack.Text.JsonSerializer<SomeObject>();
var esResult = sr.DeserializeFromString(responseJson);

responseJson 是来自 ElasticSearch 的 GET。

我得到的字段是空的。 如果我有没有空格的密钥,它会正常反序列化,我得到 IList<KeyValuePair<string, object>>

我想您的 JSON 序列化程序会带来一些麻烦。我建议使用 Newtonsoft.Json(在 NuGet 中) 我尝试了以下代码,它工作正常:

        var o1 = new SomeObject() { spec = new List<KeyValuePair<string, object>>() };
        o1.spec.Add(new KeyValuePair<string, object>("test with spaces", 10));

        var r1 = Newtonsoft.Json.JsonConvert.SerializeObject(o1);
        Console.WriteLine(r1);
        var o2 = Newtonsoft.Json.JsonConvert.DeserializeObject<SomeObject>(r1);
        var r2 = Newtonsoft.Json.JsonConvert.SerializeObject(o2);
        Console.WriteLine(r2);

结果是

{"spec":[{"Key":"test with spaces","Value":10}]}
{"spec":[{"Key":"test with spaces","Value":10}]}

没有空值,一切正常。

编辑:我实际上看不出任何理由,为什么空格根本不是问题。它们只是字符串的一部分。

如果您不介意使用 Newtonsoft.Json:

    const string json = @"{""spec"": { ""SOMETHING WITH SPACES"" : ""10"", ""SOMETHING WITH MORE SPACES"" : ""20"" }}";
    dynamic data = JsonConvert.DeserializeObject(json);
    Dictionary<string, string> list = data["spec"].ToObject<Dictionary<string, string>>();
    foreach (var item in list)
    {
        Console.WriteLine(item.Key + ", " + item.Value);
    }

你不能在这里使用IListList,因为你的来源JSON里面没有[ ],如果你想解析这是一个要求成这样的合集。换句话说,如果没有 [ ],您将无法解析为一个集合,至少在不经过大量循环的情况下无法解析。

相反,您需要按照评论中的建议使用词典。

注意:我使用了 Newtonsoft JsonConvert,因为您没有说明您的解析器是什么,但这对我的论点应该没有什么影响。

工作代码:

var json = "{ \"spec\": { \"SOMETHING WITH SPACES\" : \"10\" } }";
var someObj = JsonConvert.DeserializeObject<SomeObject>(json);

public class SomeObject
{
    public Dictionary<string, object> spec{ get; set; }
}

之后,您可以将 spec 属性 转换为 IEnumerable 并循环遍历找到的任何内容:

foreach (var pair in someObj.spec as IEnumerable<KeyValuePair<string, object>>)
{
    Console.WriteLine(pair.Key + " -> " + pair.Value);
}

甚至将其转换为列表:

var list = someObj.spec.ToList();
foreach (var pair in list)
{
    Console.WriteLine(pair.Key + " -> " + pair.Value);
}

.NET Fiddle: https://dotnetfiddle.net/15l2R3