2015-06-16 3 views
0

У меня есть проблема с разбора следующие JSON объекта:Невозможно разобрать объект JSON с Newtonsoft.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" 
    }, 
    ... 

Насколько я знаю, это Сервер1 ..., Сервер2 ... не должно быть переменных, должен быть написан «сервер» или что-то в этом роде. Я использую Newtonsoft.JSON для анализа этих данных, но я не могу десериализовать его. Я всегда получаю нулевые значения. Например, это мой видеоисточника класс

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

Как я уже сказал, я получаю нулевые значения. Что не так?

+1

JSON - это массив, а не один объект, вам нужно десериализовать его в список или массив. Вы пытались изменить 'dynamic' на' var' и посмотрели, что тип находится в отладчике? Я думаю, что 'DeserializeObject' возвращает объект, а не динамический объект. –

+0

@RonBeyer Да, это массив. Как бы это разобрать? Когда я изменяю на 'var', он говорит, что это typeof' object'. Когда я пытаюсь десериализировать это следующим образом: 'var source = JsonConvert.DeserializeObject (obj);' Я получаю нулевые значения (конечно, потому что это массив значений). Я не знаю, что делать ... – nighthawk

+1

@RonBeyer: Это не массив. Нет скобок ('' и '' '). Это всего лишь один объект с несколькими свойствами, которые, в свою очередь, обладают собственными свойствами. –

ответ

3

Рабочего LINQPad пример:

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

Да, я вижу, что на этот раз я был слишком медленным :) –

+0

Слишком медленно, но ваше решение работает;). Благодаря! – nighthawk

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

Затем он должен работать!

UPDATE

Когда вы не имеете никакого контроля над вашим 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()); 
} 
+0

Невозможно сделать, службы возвращают данные, как в моем первом сообщении ... Имейте это в виду в этой форме. – nighthawk

+2

Затем попробуйте десериализацию с помощью 'JsonConvert.DeserializeObject <Словарь > (jsonString);' – Mateusz

+0

обновил мой ответ – stefankmitph

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)

-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" 
}}] 
+0

Уже решена ... Также, к сожалению, у меня нет контроля над данными JSON. Я получаю это как есть, с видеосервера. – nighthawk

+1

хорошо, вы можете использовать, что я написал. Ответ, который вы проверили в порядке, игнорирует имена серверов. Мой код включает имя сервера в качестве ключа. – cevatsenturk

+0

Да, решения и имя сервера не имеют значения, поскольку оно указано в переменной «origin». Но все равно спасибо! – nighthawk

Смежные вопросы