Образец сериализации слабо типизированных данных JSON
При сериализации пользовательского типа в заданный формат передачи или при десериализации формата передачи в пользовательский тип заданный пользовательский тип должен быть доступен как службе, так и клиенту. Обычно для этого к пользовательским типам применяется атрибут DataContractAttribute, а к их членам применяется атрибут DataMemberAttribute. Этот механизм также применим при работе с объектами JSON, как описано в разделе Как сериализовать и десериализовать данные JSON.
В некоторых сценариях службе или клиенту Windows Communication Foundation (WCF) требуется обращаться к объектам JSON, созданным службой или клиентом, которыми разработчик не может управлять. Чем большее число веб-служб публично предоставляют интерфейсы API в формате JSON, тем менее практично для разработчика WCF создавать локальные пользовательские типы, в которые будут десериализовываться произвольные объекты JSON. В этом образце описан механизм, позволяющий разработчикам 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"]
см. в разделе Сопоставление JSON и 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 https://localhost:8000/.
To view the JSON output from the sample, navigate to https://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, как описано в разделе Построение образцов Windows Communication Foundation.
Запустите решение.
Примечание |
---|
Образцы уже могут быть установлены на компьютере. Перед продолжением проверьте следующий каталог (по умолчанию).
<диск_установки>:\WF_WCF_Samples
Если этот каталог не существует, перейдите на страницу Образцы Windows Communication Foundation (WCF) и Windows Workflow Foundation (WF) для .NET Framework 4, чтобы загрузить все образцы Windows Communication Foundation (WCF) и WF. Этот образец расположен в следующем каталоге.
<диск_установки>:\WF_WCF_Samples\WCF\Scenario\Ajax\WeaklyTypedJson
|