如何反序列化 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);
}
你不能在这里使用IList
或List
,因为你的来源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
我在将 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);
}
你不能在这里使用IList
或List
,因为你的来源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