Json и C#.
Json - формат передачи данных, который буквально за несколько лет стал вровень с XML, а в некоторых аспектах даже перегнал его. Facebook, Twitter, и многие популярные сервисы используют этот формат для выдачи данных в своих API.
Существует куча сторонних библиотек для работы с Json в .net, но зачем пользоваться сторонними продуктами, если в .net присутствует всё необходимое для этих целей.
Для примера будем использовать такой Json:
{
"firstName": "Иван",
"lastName": "Иванов",
"address": {
"streetAddress": "Московское ш., 101, кв.101",
"city": "Ленинград",
"postalCode": 101101
},
"phoneNumbers": [
"812 123-1234",
"916 123-4567"
]
}
Как видите, имеется некая информация о человеке: имя, фамилия, адрес, и его контактные телефоны. При работе с Json, данные могут сериализовываться/десериализовываться. То есть, любой класс описанный в C# мы свободно можем сериализовать и получить чистый Json. Десериализация работает по-другому: на входе у нас имеется Json, а на выходе должен получиться экземпляр класса, со свойствами описанными в Json. Естественно, что этот класс должен быть перед десериализацией подобающим образом определён.
Опишем класс Person:
public class Person
{
public string firstName { get; set; }
public string lastName { get; set; }
public Address address { get; set; }
public string[] phoneNumbers { get; set; }
public class Address
{
public string streetAddress { get; set; }
public string city { get; set; }
public int postalCode { get; set; }
}
}
Как видите, свойства класса должны соответствовать полям, что находятся в Json.
Для работы с Json необходимо подключить Reference System.Runtime.Serialization. Там находится пространство имён Json, его и будем использовать. Нам нужен класс DataContractJsonSerializer. Код для десериализции будет следующий:
using System.Runtime.Serialization.Json;
...
private void ParseBtn_Click(object sender, EventArgs e)
{
DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(Person));
string fileContent=System.IO.File.ReadAllText("json.txt");
Person person = (Person)json.ReadObject(new System.IO.MemoryStream(Encoding.UTF8.GetBytes(fileContent)));
}
Один из конструкторов DataContractJsonSerializer принимает тип класса в который будет происходить десериализация. Далее мы вызываем метод ReadObject, принимающий поток с данными Json.
Если всё было сделано верно, то экземпляр класса Person будет создан и его свойства будут заполнены в соответствии с Json.
В дальнейшем, можно вывести эти данные, например так:
FNameLbl.Text = person.firstName;
LNameLbl.Text = person.lastName;
PhonesLbl.Text = string.Join(", ", person.phoneNumbers);
StreetLbl.Text = person.address.streetAddress;
CityLbl.Text = person.address.city;
PostalLbl.Text = person.address.postalCode.ToString();
Всё должно работать, но есть один нюанс. Как вы наверно уже поняли, десериализация требует наличия в классе свойств, которые по имени совпадают с полями в Json. Так, например, в нашем Json все поля написаны с прописной буквы, и потому в классе Person тоже все свойства описаны идентично. Сами понимаете, что с точки зрения C# это недопустимо. Свойства класса должны начинаться с заглавной буквы.
Дабы решить эту проблему и не привязывать десериализацию к именам свойств класса, необходимо использовать атрибуты свойств и классов.
Наш класс с использованием атрибутов будет выглядеть так:
[DataContract]
public class Person
{
[DataMember(Name = "firstName")]
public string FirstName { get; set; }
[DataMember(Name = "lastName")]
public string LastName { get; set; }
[DataMember(Name = "address")]
public Address PersonAddress { get; set; }
[DataMember(Name = "phoneNumbers")]
public string[] PersonPhones { get; set; }
}
[DataContract]
public class Address
{
[DataMember(Name = "streetAddress")]
public string StreetAddress { get; set; }
[DataMember(Name = "city")]
public string City { get; set; }
[DataMember(Name = "postalCode")]
public int Postal { get; set; }
}
Теперь наш класс соответствует негласным правилам C#.
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.