Reputation: 61
I have a big problem with deserializing my JSON to an object. It should be deserialized to IList<KeyValuePair<string, object>>
the problem is that the keys have white spaces.
"spec": {
"SOMETHING WITH SPACES" : "10"
etc.
...
}
public class SomeObject
{
...
public IList<KeyValuePair<string, object>> spec{ get; set; }
...
}
Deserializing code:
var sr = new ServiceStack.Text.JsonSerializer<SomeObject>();
var esResult = sr.DeserializeFromString(responseJson);
responseJson
is a GET from ElasticSearch.
What I get to my field it is null.
If I have key without whitespaces it's deserializing normally and I'm getting my IList<KeyValuePair<string, object>>
Upvotes: 1
Views: 2088
Reputation: 24136
You can't use IList
or List
here, because your source JSON has no [ ]
in it, which is a requirement if you want to parse into such a collection. In other words, without [ ]
you can't parse into a collection, at least not without going through lots of hoops.
Instead you need to use a Dictionary as was suggested already in comments.
Note: I used Newtonsoft JsonConvert because you didn't state what your parser is, but that should make little or no difference to my arguments.
Working code:
var json = "{ \"spec\": { \"SOMETHING WITH SPACES\" : \"10\" } }";
var someObj = JsonConvert.DeserializeObject<SomeObject>(json);
public class SomeObject
{
public Dictionary<string, object> spec{ get; set; }
}
After that, you can cast the spec
property to an IEnumerable
and loop through whatever was found:
foreach (var pair in someObj.spec as IEnumerable<KeyValuePair<string, object>>)
{
Console.WriteLine(pair.Key + " -> " + pair.Value);
}
Or even convert it to a List:
var list = someObj.spec.ToList();
foreach (var pair in list)
{
Console.WriteLine(pair.Key + " -> " + pair.Value);
}
.NET Fiddle: https://dotnetfiddle.net/15l2R3
Upvotes: 2
Reputation: 1341
I guess your JSON serialiazer makes some trouble. I'd recommend to use Newtonsoft.Json (in NuGet) I've tried following code, and it works fine:
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);
The outcome is
{"spec":[{"Key":"test with spaces","Value":10}]}
{"spec":[{"Key":"test with spaces","Value":10}]}
No null values, all works fine.
EDIT: I actually see no reason, why spaces should be any problem at all. They are just part of the string.
Upvotes: 0
Reputation: 1336
If you don't mind using 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);
}
Upvotes: 0