(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Создание WCF сервиса для JSON

Источник: msug

В субботу я впервые выступил с докладом в Southern California Code Camp о том, как использовать JQuery, для выполнения AJAX-операций к конечной точке(endpoint) в WCF. Сегодня я хочу показать, как создать WCF сервис с поддержкой JSON и каким образом создавать сообщения, которые могут сереализоваться в JSON и обратно.

Первым шагом будет добавление WCF сервиса к веб-сайту. Это может быть ваш текущий проект, хотя это не обязательно. При добавлении сервиса через Visual Studio 2008 у нас создаётся svc-файл, а также контент, который, в нашем случае, необходимо удалить.

Visual Studio 2008 and .NET 3.5

Visual Studio 2010 вот-вот появится, поэтому я попробую сделать это двумя способами. В течении нескольких дней я напишу о том, как сделать это с помощью Visual Studio 2010. В диалогом окне Add New Item выберите WCF Service. После этого к вашему веб-сайту добавится файл .svc, а так же ещё два файла и некоторые ненужные секции в файле web.config.

Начнём с файлов, добавленных в проект. Файл (.vb или .cs) определяет интерфейс, реализуемый сервисом. В нём так же находятся атрибуты, говорящие WCF о том, как использовать сервис. К .svc файлу также добавляется code-behind файл, в котором описана реализация сервиса. Оба эти файла можно использовать, однако я предпочитаю удалять их. Вместо этого я создам библиотеку классов, которая будет содержать и интерфейс, и реализацию. В конечном итоге это более понятный путь для дальнейшего управления кодом ваших WCF сервисов. Во-первых это позволяет легче создавать unit тесты (я опишу это в другом докладе). Во-вторых это даёт определённую гибкость при добавлении другого поставщика, реализующего интерфейс сервиса. Вы увидите, что такой путь не усложнит разработку, а всего лишь потребует добавления ссылки на библиотеку с классом.

Файл Web.config слегка загрязнился, потому что были добавлены ненужные секции behaviors, services и endpoint в секцию system.serviceModel. Ниже приведен пример добавленной конфигурации, которую можно смело удалять из файла.

<behaviors>
  <serviceBehaviors>
    <behavior name="Web.TestsvcBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<services>
  <service behaviorConfiguration="Web.TestsvcBehavior" name="Web.Testsvc">
    <endpoint address="" binding="wsHttpBinding" contract="Web.ITestsvc">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>
<bindings>
  <basicHttpBinding>
    <binding name="basicHttp" maxReceivedMessageSize="2147483647">
      <security mode="None"/>
    </binding>
  </basicHttpBinding>
</bindings>

В конечном итоге это сводится к конфигурации сервиса, и я не буду отрицать, что мало знаю о конфигурировании WCF. У меня есть люди для этого. Поэтому, двинемся дальше, а в этом месте вам придётся поверить мне на слово.

Единственное, что осталось изменить - это .svc файл для корректной реализации нашего сервиса. Вот пример директивы, которая по умолчанию задаётся в .svc файле.

<%@ servicehost language="C#" debug="true" service="Web.Testsvc" codebehind="Testsvc.svc.cs" %>

Ниже показана новая версия директивы, в которой указано, какой класс будет использоваться для реализации сервиса, а так же подключен класс WebScriptServiceHostFactory, который позволяет использовать веб протоколы и добавляет JSON сериализацию, которая нам необходима для работы нашего сервиса с JQuery Ajax.

<%@ ServiceHost Language="C#"
    Service="WCFJQuery.ContactBLL.Implementation.TestSvc"
    Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" %>

Библиотека классов

Следующим шагом добавим класс для реализации сервиса. Я люблю располагать файлы в папках, указывающих их назначение. Вы можете располагать как вам угодно. Я создал папку Contracts, которая содержит интерфейсы сервиса. Я говорю во множественном числе, потому что ваше приложение может содержать много WCF сервисов.

Атрибуты WCF находятся в пространстве имён System.ServiceModel, поэтому вам нужно добавить на него ссылку. Если вы используете инструмент R#, то он сам добавит ссылку, как только вы напишете первый атрибут. Первый файл, который мы добавим - это интерфейс сервиса. В нашем примере я использую контактную форму, поэтому сервис называется ContactUs. Следовательно интерфейс будется называться IContactUs.cs.

Если вы помните, в интерфейсе, который мы удалили, класс был отмечен атрибутом ServiceContract. Сейчас мы определим пространство имён для интерфейса, имени сервиса, режима сессии и уровня защиты.

[ServiceContract(Namespace = "urn:WCFJQuery.ContactBLL.Contracts",
    Name = "ContactUs",
    SessionMode = SessionMode.NotAllowed,
    ProtectionLevel = ProtectionLevel.None)]

Теперь мы можем добавить сигнатуры методов в наш интерфейс. Для нашего приложения добавим 4 метода: PostNewContact, GetContact, GetActiveContacts и BadMethod. Каждый метод описывается как указано ниже:

[OperationContract(IsTerminating = false,
    IsInitiating = true,
    IsOneWay = false,
    AsyncPattern = false,
    Action = "PostNewContact",
    ProtectionLevel = ProtectionLevel.None)]
PostNewContactResponse PostNewContact(PostNewContactRequest request);

Далее, мы можем добавить класс для реализации сервиса. Я помещу этот файл в папку Implementation. Создаём файл ContactUs.cs. Класс ContactUs реализует интерфейс IContactUs и описан атрибутом ServiceBehavior. В этом примере свойство IncludeExceptionDetailInFaults установлено в true. Это сделано для того, что бы сообщения об исключениях отправлялись на клиент сериализуясь в нужном виде. В нашем случае JQuery получит JSON данные.

Члены класса не обязательно описывать какими-нибудь атрибутами. Вы можете подключить их автоматически, используя SmartTag на имени интерфейса или инструменты типа R# или CodeRush.

Сейчас у вас должны быть ссылки на классы, которые не существуют. Мы должны создать их. Они так же добавляются в папку Implementation. Каждый из этих классов - класс сообщений. Эти классы содержат тело сообщений, которое является содержимым запроса к сервису и ответа от него.

Пока вы окончательно не потерялись, нужно кое что прояснить. Архитектура WCF и SOA основана на передаче сообщений и объектов. Обычно, каждый метод сервиса принимает и возвращает какой-либо объект.

Я всегда люблю проверять возвращаемый объект на клиенте. В этом различие между мной и тем, кто сфокусирован на разработке WCF части приложения. Первым, что меня натолкнуло на это, был метод, который добавлял новую запись в базу данных. Автор метода не возвращал никакого подтверждающего значения или вообще какого-либо значения, просто null. Он объяснял это тем, что если что то не сработает, то сгенерируется исключение. Я думаю это плохая практика в любом коде, так как вы не должны показывать исключение клиенту. Вместо этого, вы должны обработать исключение и вернуть осмысленное значение. Вы можете прочитать больше об этом в книге Брэда Абрамса.

Давайте вернёмся к коду и посмотрим что нужно передать в запрос для того, что бы вернуть объект "Контакт". Очевидно что методу сервиса необходим ContactId, который используется как ключ для объекта "Контакт".

Обратите внимание, я не говорю о записе в таблице "Контакты", потому что современные приложения работают с моделью данных, а не с базой на прямую. Например Entity Framework, oData или nHibernate. Фактически объект "Контакт" может быть составлен из записей разных таблиц.

Класс GetContactRequest должен быть сериализован с помощью WCF, поэтому нам необходимо добавить атрибут DataContact к классу и атрибут DataMember для каждого члена класса. В этом атрибуте определяется имя члена класса. Оно может быть любым, но вам нужно запомнить его для доступа на клиенте. Затем мы должны указать, что это значение обязательно(IsRequired=true), иначе мы попытаемся выполнить запрос без указания id контакта, который нам нужен. В конце нужно указать порядок расположения данных.(Order = 0). Это подразумевает то, что значение будет первым или с индексом 0 в сериализуемом объекте.

using System.Runtime.Serialization;

namespace WCFJQuery.ContactBLL.Implementation {

[DataContract(Namespace = "urn:WCFJQuery.ContactBLL.Implementation",
Name = "GetContactRequest")]

    public class GetContactRequest {
        [DataMember(Name = "ContactId", IsRequired = true, Order = 0)]
        public int ContactId { get; set; }

    }
}

Для класса GetContactResponse нужно подключить пространство имён System.Runtime.Serialization и добавить необходимые атрибуты. В этом классе находится всего один член - объект класса ContactInfo.

using System.Runtime.Serialization;

namespace WCFJQuery.ContactBLL.Implementation {

[DataContract(Namespace = "urn:WCFJQuery.ContactBLL.Implementation",
Name = "GetActiveContactsRequest")]

    public class GetContactResponse {
        [DataMember(Name = "ContactInfo", IsRequired = true, Order = 0)]
        public ContactInfo contactInfo { get; set; }

    }
}

Класс ContactInfo так же требует сериализации. Поэтому вы опять добавляете необходимые атрибуты. Класс ContaсtInfo содержит более одного члена класса, некоторые помечены атрибутом IsRequired, некоторые нет. В этот раз вы задаёте порядок расположения данных с индексом в диапазоне от 1 до 11.

using System.Runtime.Serialization;

namespace WCFJQuery.ContactBLL.Implementation {

    [DataContract(Namespace = "urn:WCFJQuery.ContactBLL.Implementation",
    Name = "ContactInfo")]
    public class ContactInfo {

        [DataMember(Name = "ContactId", IsRequired = false, Order = 0)]
        public int ContactId { get; set; }

        [DataMember(Name = "FirstName", IsRequired = true, Order = 1)]
        public string FirstName { get; set; }

    ...

        [DataMember(Name = "Coment", IsRequired = true, Order = 11)]
        public string Comment { get; set; }

    }
}

Процесс создания оставшихся объектов для передачи с запросом к серверу и объектов ответа от сервера точно такой же. Запомните - любые передаваемые объекты должны сериализоваться, т.е. должны быть помечены атрибутами. Вы не обязаны добавлять ваши классы реализации в библиотеку классов, но как вы увидите в последующих докладах, это облегчает тестирование вашего кода.

Теперь у нас есть готовый WCF веб-сервис, принимающий и возвращающий JSON объекты, которые могут быть использованы на клиенте. В следующем докладе мы рассмотрим инфраструктуру и реализацию AJAX вызовов, использующих JSON к WCF сервису.

Исходный код

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 12.04.2010 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год.
Microsoft Office для дома и учебы 2019 (лицензия ESD)
Microsoft Windows Professional 10, Электронный ключ
Microsoft 365 Business Standard (corporate)
Microsoft 365 Apps for business (corporate)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
Краткие описания программ и ссылки на них
Новые программы для Windows
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100