Reputation: 832
I have a problem with parsing following JSON object:
{
"SERVER1/DeviceIpint.3/SourceEndpoint.video:0:0" :
{
"origin" : "SERVER1/DeviceIpint.3/SourceEndpoint.video:0:0",
"state" : "connected",
"friendlyNameLong" : "Camera 3",
"friendlyNameShort" : "3"
},
"SERVER2/DeviceIpint.5/SourceEndpoint.video:0:0" :
{
"origin" : "SERVER2/DeviceIpint.5/SourceEndpoint.video:0:0",
"state" : "disconnected",
"friendlyNameLong" : "Camera 5",
"friendlyNameShort" : "5"
},
...
As far as i know, this Server1..., Server2... shouldn't be variables, there should be written "server" or something like that. I am using Newtonsoft.JSON to parse this data but i can't deserialize it. I always get null values. For example, this is my VideoSource class
private class VideoSource
{
public string origin { get; set; }
public string state { get; set; }
public string friendlyNameLong { get; set; }
public string friendlyNameShort { get; set; }
public override string ToString()
{
return origin;
}
}
and I'm trying to parse it with following function:
private VideoSource ParseJsonToVideoSource(string obj)
{
dynamic source = JsonConvert.DeserializeObject(obj);
VideoSource s = new VideoSource();
s.origin = source.origin;
s.friendlyNameLong = source.friendlyNameLong;
s.friendlyNameShort = source.friendlyNameShort;
s.state = source.state;
return s;
}
As I said, i get null values. What's wrong?
Upvotes: 0
Views: 2634
Reputation: 31
Your json data is actually list like dictionary key value pair. Key is server name. You can parse like this.
public Dictionary<string, VideoSource> ParseJsonToVideoSource(string obj)
{
Dictionary<string, VideoSource> result = new Dictionary<string, VideoSource>();
dynamic sources = JsonConvert.DeserializeObject(obj);
foreach (var source in sources)
{
VideoSource s = new VideoSource();
s.origin = source.Value.origin;
s.friendlyNameLong = source.Value.friendlyNameLong;
s.friendlyNameShort = source.Value.friendlyNameShort;
s.state = source.Value.state;
result.Add(source.Name, s);
}
return result;
}
but i think, json has to be like this.
[
{"name":"SERVER1/DeviceIpint.3/SourceEndpoint.video:0:0",
"info" :
{
"origin" : "SERVER1/DeviceIpint.3/SourceEndpoint.video:0:0",
"state" : "connected",
"friendlyNameLong" : "Camera 3",
"friendlyNameShort" : "3"
}},
{name:"SERVER2/DeviceIpint.5/SourceEndpoint.video:0:0",
info:
{
"origin" : "SERVER2/DeviceIpint.5/SourceEndpoint.video:0:0",
"state" : "disconnected",
"friendlyNameLong" : "Camera 5",
"friendlyNameShort" : "5"
}}]
Upvotes: -1
Reputation: 1650
Working LinqPad example:
void Main()
{
string obj = @"{
""SERVER1/DeviceIpint.3/SourceEndpoint.video:0:0"" :
{
""origin"" : ""SERVER1/DeviceIpint.3/SourceEndpoint.video:0:0"",
""state"" : ""connected"",
""friendlyNameLong"" : ""Camera 3"",
""friendlyNameShort"" : ""3""
},
""SERVER2/DeviceIpint.5/SourceEndpoint.video:0:0"" :
{
""origin"" : ""SERVER2/DeviceIpint.5/SourceEndpoint.video:0:0"",
""state"" : ""disconnected"",
""friendlyNameLong"" : ""Camera 5"",
""friendlyNameShort"" : ""5""
}
}";
VideoSource s = new VideoSource();
dynamic source = JsonConvert.DeserializeObject<Dictionary<string, VideoSource>>(obj);
foreach(var videoSource in source)
{
s.origin = videoSource.Value.origin;
s.friendlyNameLong = videoSource.Value.friendlyNameLong;
s.friendlyNameShort = videoSource.Value.friendlyNameShort;
s.state = videoSource.Value.state;
s.Dump();
}
}
// Define other methods and classes here
public class VideoSource
{
public string origin { get; set; }
public string state { get; set; }
public string friendlyNameLong { get; set; }
public string friendlyNameShort { get; set; }
public override string ToString()
{
return origin;
}
}
Upvotes: 3
Reputation: 3306
I'd form an array out of it like this:
[
{
"origin": "SERVER1/DeviceIpint.3/SourceEndpoint.video:0:0",
"state": "connected",
"friendlyNameLong": "Camera 3",
"friendlyNameShort": "3"
},
{
"origin": "SERVER2/DeviceIpint.5/SourceEndpoint.video:0:0",
"state": "disconnected",
"friendlyNameLong": "Camera 5",
"friendlyNameShort": "5"
}
]
and deserialize it like this:
var result = JsonConvert.DeserializeObject<List<VideoSource>>(jsonString);
Then it should work!
UPDATE
When you have no control over your json, do it this way:
string json =
"{\"SERVER1/DeviceIpint.3/SourceEndpoint.video:0:0\":{\"origin\":\"SERVER1/DeviceIpint.3/SourceEndpoint.video:0:0\",\"state\":\"connected\",\"friendlyNameLong\":\"Camera 3\",\"friendlyNameShort\":\"3\"},\"SERVER2/DeviceIpint.5/SourceEndpoint.video:0:0\":{\"origin\":\"SERVER2/DeviceIpint.5/SourceEndpoint.video:0:0\",\"state\":\"disconnected\",\"friendlyNameLong\":\"Camera 5\",\"friendlyNameShort\":\"5\"}}";
dynamic result = JsonConvert.DeserializeObject(json);
foreach (JProperty property in result)
{
var myVideoSource = JsonConvert.DeserializeObject<VideoSource>(property.Value.ToString());
}
Upvotes: 0
Reputation: 174299
A simple way would be this:
dynamic source = JsonConvert.DeserializeObject<ExpandoObject>(json);
foreach(var videoSource in source)
{
// Here you can access videoSource.origin, videoSource.state etc.
}
An ExpandoObject
is actually just a dictionary, so you could also deserialize into a dictionary with your VideoSource
as the value:
var videoSources = JsonConvert.DeserializeObject<Dictionary<string, VideoSource>>(json);
foreach(var videoSource in source)
{
// videoSource is of type VideoSource
}
(This has already been noted by Mateusz in his comment)
Upvotes: 2