无法使用Newtonsoft.JSON

时间:2015-06-16 12:11:22

标签: c# json json.net

我在解析以下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" 
    },
    ...

据我所知,这个Server1 ...,Server2 ......不应该是变量,应该写'&34; server"或类似的东西。我使用Newtonsoft.JSON来解析这些数据,但我无法对其进行反序列化。我总是得到空值。例如,这是我的VideoSource类

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

我尝试使用以下功能解析它:

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

正如我所说,我得到空值。怎么了?

4 个答案:

答案 0 :(得分:3)

使用LinqPad示例:

#cover-img

答案 1 :(得分:2)

一个简单的方法是:

dynamic source = JsonConvert.DeserializeObject<ExpandoObject>(json);
foreach(var videoSource in source)
{
    // Here you can access videoSource.origin, videoSource.state etc.
}

ExpandoObject实际上只是一个字典,因此您也可以将VideoSource作为值反序列化为字典:

var videoSources = JsonConvert.DeserializeObject<Dictionary<string, VideoSource>>(json);
foreach(var videoSource in source)
{
    // videoSource is of type VideoSource
}

(Mateusz在his comment

中已经注意到了这一点

答案 2 :(得分:0)

我会像这样形成一个阵列:

[
    {
        "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"
    }
]

并将其反序列化为:

var result = JsonConvert.DeserializeObject<List<VideoSource>>(jsonString);

然后它应该工作!

<强>更新

当你无法控制你的json时,就这样做:

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

答案 3 :(得分:-1)

您的json数据实际上是列表,如字典键值对。密钥是服务器名称。你可以像这样解析。

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

但我想,json必须是这样的。

[ 
{"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" 
}}]