2013-08-29 3 views
10

Я получаю следующий ответ от веб-сервиса:Как сделать C# объект из JSON

{ 
    "data":{ 
    "foo.hugo.info": { 
     "path": "logon.cgi", 
     "minVersion": 1, 
     "maxVersion": 2 
    }, 
    "foo.Fritz.Task": { 
     "path": "Fritz/process.cgi", 
     "minVersion": 1, 
     "maxVersion": 1 
    } 
    }, 
    "success": true 
} 

Как должны JSON-объект выглядеть следующим десериализовать это?

Или есть другой способ получить значения свойств?

+0

Вы хотите его десериализовать? – Shaharyar

+0

Что вы хотите делать с информацией, как только вы ее приобрели в своей программе? Хотя вы можете десериализовать его в объект, это может быть работой, которую вы можете избежать, в зависимости от вашей цели. –

+0

У вас уже есть объект JSON. Вы имеете в виду, как перевести его в объект C#? Если это сделать класс со свойствами 'путь',' minVersion', 'maxVersion' и использовать дескрипцию JSON.NET для чего-то вроде JSON.NET. –

ответ

7

С JSON.NET библиотеки это довольно тривиальным:

public class Root 
{ 
    public Dictionary<string, Data> Data { get; set; } 
    public bool Success { get; set; } 
} 

public class Data 
{ 
    public string Path { get; set; } 
    public int MinVersion { get; set; } 
    public int MaxVersion { get; set; } 
} 

, а затем:

string json = 
@"{ 
    ""data"":{ 
    ""foo.hugo.info"": { 
     ""path"": ""logon.cgi"", 
     ""minVersion"": 1, 
     ""maxVersion"": 2 
    }, 
    ""foo.Fritz.Task"": { 
     ""path"": ""Fritz/process.cgi"", 
     ""minVersion"": 1, 
     ""maxVersion"": 1 
    } 
    }, 
    ""success"": true 
}"; 
Root root = JsonConvert.DeserializeObject<Root>(json); 

В этом примере я использовал Dictionary<string, Data> объект для моделирования 2 сложных ключей (foo.hugo.info и foo.Fritz.Task), потому что они содержат имена, которые не могут использоваться в .NET-члене.

+0

Любая причина для понижения? Пожалуйста, оставьте комментарий, когда downvoting объясняет, почему этот ответ неверен. –

+0

Он делает именно то, что мне нужно! Также он использует словарь и может обрабатывать более двух записей данных. Спасибо! – GreenEyedAndy

1

проверить этот сайт: http://json2csharp.com/

Вставить в строку JSON, и она будет генерировать классы для вас. Обычно я использую это в руке с JSON.NET для десериализации экземпляра корневого объекта.

+1

Домашняя страница JSON.NET: http://json.codeplex.com/ – valverij

+1

Пожалуйста, внимательно ознакомьтесь с JSON и обратите внимание на клавиши 'foo.hugo.info' и' foo.Fritz.Task'. Теперь посмотрим, какой сайт, который вы предложили создать для класса 'Data', довольно бесполезен. –

+0

Хорошая точка. Раньше у меня не было проблем с сайтом. +1 за лучший ответ. – stevepkr84

5

Если вы используете VS2012 или выше, вы можете сделать следующее:

Edit > Paste Special > Paste JSON As Classes 

С вашего примера, это приводит:

public class Rootobject 
{ 
    public Data data { get; set; } 
    public bool success { get; set; } 
} 

public class Data 
{ 
    public FooHugoInfo foohugoinfo { get; set; } 
    public FooFritzTask fooFritzTask { get; set; } 
} 

public class FooHugoInfo 
{ 
    public string path { get; set; } 
    public int minVersion { get; set; } 
    public int maxVersion { get; set; } 
} 

public class FooFritzTask 
{ 
    public string path { get; set; } 
    public int minVersion { get; set; } 
    public int maxVersion { get; set; } 
} 
+1

Любой пример кода, какой сериализатор вы использовали бы для десериализации JSON, показанного в OP для этих классов? Меня особенно интересуют свойства 'foohugoinfo' и' fooFritzTask'. –

+0

Это не может полностью ответить на вопрос OP, но я должен сказать ... mind = blown. Я понятия не имел, что скрывалось под меню редактирования до сих пор. –

+2

Это не является гибким, если добавлен третий вариант, вам нужно будет создать еще один класс и добавить его в класс 'Data' как свойство. – christiandev

1

Вы можете использовать DataContractJsonSerializer

[DataContract] 
    public class DetailedData 
    { 
     [DataMember(Name="path")] 
     public string Path { get; set; } 
     [DataMember(Name = "minVersion")] 
     public int MinVersion { get; set; } 
     [DataMember(Name = "maxVersion")] 
     public int MaxVersion { get; set; } 
    } 

    [DataContract] 
    public class Data 
    { 
     [DataMember(Name = "foo.hugo.info")] 
     public DetailedData Info { get; set; } 
     [DataMember(Name = "foo.Fritz.Task")] 
     public DetailedData Task { get; set; } 
    } 

    [DataContract] 
    public class RootObject 
    { 
     [DataMember(Name = "data")] 
     public Data Data { get; set; } 
     [DataMember(Name = "success")] 
     public bool Success { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     string json = "..."; 
     DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(RootObject)); 

     RootObject obj = (RootObject)js.ReadObject(new MemoryStream(Encoding.Unicode.GetBytes(json))); 
     Console.WriteLine(obj.Data.Task.MaxVersion); 
    } 

Редактировать: этот класс для Info и Task

+0

Вы могли бы использовать один и тот же класс для 'Info' и' Task'. Кроме этого, хороший и полный ответ, +1. –

+0

Я только что закончил редактирование :) –

+0

Это хорошо работает, но я забыл написать, что данные: динамичны. Это может быть любое количество разных элементов, но каждый раз с элементами пути, minVersion и maxVersion. Только имена (foo.hugo.info/foo.fritz.task) могут различаться. – GreenEyedAndy