Пример сериализации слабо типизированных данных JSON
При сериализации пользовательского типа в заданный формат передачи или при десериализации формата передачи в пользовательский тип заданный пользовательский тип должен быть доступен как службе, так и клиенту. Обычно для этого к пользовательским типам применяется атрибут DataContractAttribute , а к их членам применяется атрибут DataMemberAttribute . Этот механизм также применим при работе с объектами JSON, как описано в разделе How to: Serialize and Deserialize JSON Data.
В некоторых сценариях служба Windows Communication Foundation (WCF) или клиент должны получить доступ к объектам JSON, созданным службой или клиентом, находящимся за пределами управления разработчиком. Поскольку дополнительные веб-службы публично предоставляют API JSON, разработчик WCF может создавать локальные определяемые пользователем типы, в которых десериализация произвольных объектов JSON может стать непрактичным.
Пример WeaklyTypedJson предоставляет механизм, позволяющий разработчикам WCF работать с десериализированными, произвольными объектами JSON без создания определяемых пользователем типов. Он называется слабо типизированной сериализацией объектов JSON, поскольку тип, в который десериализуется объект JSON, во время компиляции неизвестен.
Например, API общедоступной веб-службы возвращает следующий объект JSON, который содержит определенные сведения о пользователе службы.
{"personal": {"name": "Paul", "age": 23, "height": 1.7, "isSingle": true, "luckyNumbers": [5,17,21]}, "favoriteBands": ["Band ABC", "Band XYZ"]}
Для десериализации этого объекта клиент WCF должен реализовать следующие определяемые пользователем типы.
[DataContract]
public class MemberProfile
{
[DataMember]
public PersonalInfo personal;
[DataMember]
public string[] favoriteBands;
}
[DataContract]
public class PersonalInfo
{
[DataMember]
public string name;
[DataMember]
public int age;
[DataMember]
public double height;
[DataMember]
public bool isSingle;
[DataMember]
public int[] luckyNumbers;
}
Эта задача может быть громоздкой, особенно если клиент должен обрабатывать более одного типа объектов JSON.
Тип JsonObject
в этом образце является слабо типизированным представлением объекта JSON. JsonObject
использует естественное сопоставление между объектами JSON и словарями платформа .NET Framework, а также сопоставление между массивами JSON и массивами платформа .NET Framework. В следующем примере кода демонстрируется тип JsonObject
.
// Instantiation of JsonObject json omitted
string name = json["root"]["personal"]["name"];
int age = json["root"]["personal"]["age"];
double height = json["root"]["personal"]["height"];
bool isSingle = json["root"]["personal"]["isSingle"];
int[] luckyNumbers = {
json["root"]["personal"]["luckyNumbers"][0],
json["root"]["personal"]["luckyNumbers"][1],
json["root"]["personal"]["luckyNumbers"][2]
};
string[] favoriteBands = {
json["root"]["favoriteBands"][0],
json["root"]["favoriteBands"][1]
};
Обратите внимание что объекты и массивы JSON можно просматривать без необходимости объявлять их тип во время компиляции. Описание требования к объекту верхнего уровня ["root"]
см. в разделе Mapping Between JSON and XML.
Примечание.
Класс JsonObject
предоставлен исключительно в качестве примера. Он не был тщательно протестирован, и его не следует использовать в рабочей среде. Очевидным недостатком слабо типизированной сериализации JSON является плохая типобезопасность при работе с JsonObject
.
Чтобы использовать тип JsonObject
, контракт операции клиента должен использовать в качестве возвращаемого типа Message .
[ServiceContract]
interface IClientSideProfileService
{
// There is no need to write a DataContract for the complex type returned by the service.
// The client will use a JsonObject to browse the JSON in the received message.
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
Message GetMemberProfile();
}
Объект JsonObject
создается, как показано в следующем коде.
// Code to instantiate IClientSideProfileService channel omitted…
// Make a request to the service and obtain the Json response
XmlDictionaryReader reader = channel.GetMemberProfile().GetReaderAtBodyContents();
// Go through the Json as though it is a dictionary. There is no need to map it to a .NET CLR type.
JsonObject json = new JsonObject(reader);
Конструктор JsonObject
принимает объект XmlDictionaryReader, который получается через метод GetReaderAtBodyContents . Модуль чтения содержит XML-представление сообщения JSON, полученного клиентом. Дополнительные сведения см. в разделе "Сопоставление между JSON и XML".
Программа выдает следующие результаты.
Service listening at http://localhost:8000/.
To view the JSON output from the sample, navigate to http://localhost:8000/GetMemberProfile
This is Paul's page. I am 23 years old and I am 1.7 meters tall.
I am single.
My lucky numbers are 5, 17, and 21.
My favorite bands are Band ABC and Band XYZ.
Настройка, сборка и выполнение образца
Убедитесь, что вы выполнили процедуру однократной установки для примеров Windows Communication Foundation.
Создайте решение WeaklyTypedJson.sln, следуя инструкциям из раздела Building the Windows Communication Foundation Samples.
Запустите решение.