Знакомство с ADO.NET Data Services

Не так давно я рассказывал о двух взаимозаменяющих взаимодополняющих подходах к построению сервисов — SOAP и REST. На этот раз мы поговорим о технологии, которая позволит нам с легкостью строить REST-сервисы — ADO.NET Data Services.

Итак, вспомним еще раз о том, что сервис в стиле REST позволяет нам работать с данными. Это означает, что алгоритм построения сервис-ориентированной системы на базе REST будет примено следующим:

  1. Получить доступ к источнику данных (в виде объектов и объектных коллекций);
  2. Опубликовать наши коллекции в веб (буквально легкими движениями руки);
  3. Настроить права доступа и логику предоставления доступа к данным;
  4. Получить прокси-класс для работы на клиенте.

Теперь можно перейти к делу.

В своем примере я использую VS2008SP1 + SQL Server 2008. В качестве источника данных возьмем Entity Data Model (ADO.NET Entity Framework).

Для того, чтобы иметь возможность работать с ADO.NET Data Services необходимо установить ASP.NET 3.5 Extensions, либо VS2008SP1 + .NET3.5SP1.

Первым делом создадим веб-приложение ASP.NET. Добавим в наше приложение Entity Data Model. В качестве источника пусть будет база данных Northwind.

При создании модели скажем мастеру использовать все таблицы БД, получится симпотичная модель базы Northwind.

После того как источник данных готов к работе добавим в наш проект сервис. Для этого еще раз обратимся к пункту меню Add new item и из предложенных шаблонов выберем пункт ADO.NET Data Service. В итоге среда разработки создаст нам заготовку класса-сервиса. Этот класс - наследник от WebDataService<..>, который в качестве generic-параметра использует тип источника данных:

public class WebDataService1 : 
  WebDataService< /* TODO: put your data source class name here */ >
  {
    ...

Для того, чтобы наш сервис заработал, укажем в качестве generic-параметра контекст нашего источника данных (DataClasses1Context):

public class WebDataService1 : 
  WebDataService<DataClasses1Context>
  {

Следующим шагом необходимо определить видимость контейнеров для клиентов. Дело в том, что ADO.NET Data Services позволяет на уровне контейнера разграничить права доступа - одни контейнеры мы, например, можем только читать (read only), по другим - выполнять запросы и читать, а третьи - изменять.

В данный момент разрешим все для всех контейнеров. Для этого изменим статический метод InitializeService(..) и добавим к нему следующий код:

public static void InitializeService(IWebDataServiceConfiguration config)
{
  config.SetResourceContainerAccessRule("*", ResourceContainerRights.All);
}

Кроме того, что мы можем ограничить доступ к данным на уровне контейнеров, можно управлять правами на уровне операций, а также создавать свои перехватчики (interceptors). Но об этом в следующий раз.

Собственно на этом создание сервиса завершено. Теперь мы можем обратиться к нему из браузера и посмотреть что из этого получилось. В результате мы увидим наши коллекции в формате AtomPub.

Но нет толку от сервиса, когда нету клиента. Давайте реализуем клиента. Задача реализации клиента сводится к построению прокси-класса к нашему сервису. Для этого служит утилита WebDataGen. Для того, чтобы она сгенерировала нам прокси-класс запустим наш сервис и запустим webdatagen:

"C:\Program Files (x86)\Microsoft ASP.NET 3.5 Extensions\Webdatagen.exe" /uri:http://localhost:51126/NorthwindService.svc /language:CSharp /outobjectlayer:./NorthwindService.cs /mode:ClientClassGeneration

В результате работы WebDataGen получим файл NorthwindService.cs, который и содержит прокси-класс. Далее мы можем использовать этот класс где угодно — от консольных до WPF-приложений. При этом нам останется только указать адрес, по которому расположен сервис:

NorthwindDataClasses context =
  new NorthwindDataClasses(@"http://localhost:51126/NorthwindService.svc");

var q = from c in context.Customers
        select c;

Теперь наша база данных Northwind доступна через REST-сервис.