Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Майк Уосон
Скачивание завершенного проекта
Open Data Protocol (OData) — это протокол доступа к данным для Интернета. OData предоставляет универсальный способ структурирования данных, запроса данных и управления набором данных с помощью операций CRUD (создание, чтение, обновление и удаление). OData поддерживает форматы AtomPub (XML) и JSON. OData также определяет способ предоставления метаданных о данных. Клиенты могут использовать метаданные для обнаружения сведений о типах и связях для набора данных.
ASP.NET веб-API упрощает создание конечной точки OData для набора данных. Вы можете точно контролировать, какие операции OData поддерживаются конечной точкой. Можно разместить несколько конечных точек OData, а также конечных точек, отличных от OData. У вас есть полный контроль над моделью данных, внутренней бизнес-логикой и уровнем данных.
Версии программного обеспечения, используемые в руководстве
- Visual Studio 2013
- Веб-API 2
- OData версии 3
- Entity Framework 6
- Прокси-сервер веб-отладки Fiddler (необязательно)
Поддержка веб-API OData была добавлена в обновление ASP.NET и Web Tools 2012.2. Однако в этом руководстве используется каркас, добавленный в Visual Studio 2013.
В этом руководстве вы создадите простую конечную точку OData, которую клиенты могут запрашивать. Вы также создадите клиент C# для конечной точки. После завершения работы с этим руководством в следующем наборе руководств показано, как добавить дополнительные функциональные возможности, включая отношения сущностей, действия и $expand/$select.
- Создание проекта Visual Studio
- Добавление модели сущностей
- Добавление контроллера OData
- Добавьте EDM и маршрут
- Инициализация базы данных (необязательно)
- Изучение конечной точки OData
- Форматы сериализации OData
Создание проекта Visual Studio
В этом руководстве вы создадите конечную точку OData, которая поддерживает основные операции CRUD. Конечная точка предоставляет один ресурс, список продуктов. В последующих руководствах будут добавлены дополнительные возможности.
Запустите Visual Studio и выберите новый проект на начальной странице. Или в меню "Файл " выберите "Создать " и " Проект".
В области "Шаблоны " выберите "Установленные шаблоны " и разверните узел Visual C#. В разделе Visual C# выберите "Веб". Выберите шаблон веб-приложения ASP.NET .
В диалоговом окне "Создать ASP.NET проект " выберите пустой шаблон. В разделе "Добавление папок и основных ссылок на..." проверьте веб-API. Нажмите кнопку ОК.
Добавление модели сущностей
Модель — это объект, представляющий данные в приложении. Для работы с этим руководством нам нужна модель, представляющая продукт. Модель соответствует типу сущности OData.
В обозревателе решений щелкните правой кнопкой мыши папку Models. В контекстном меню выберите "Добавить ", а затем выберите "Класс".
В диалоговом окне "Добавление нового элемента" назовите класс Product.
Замечание
По соглашению классы моделей помещаются в папку Models. Вам не нужно следовать этому соглашению в собственных проектах, но мы будем использовать его для этого руководства.
В файле Product.cs добавьте следующее определение класса:
public class Product
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
Свойство ID будет ключом сущности. Клиенты могут запрашивать продукты по идентификатору. Это поле также будет первичным ключом в серверной базе данных.
Теперь создайте проект. На следующем шаге мы будем использовать некоторые шаблоны Visual Studio, которые используют отражение для поиска типа продукта.
Добавление контроллера OData
Контроллер — это класс, который обрабатывает HTTP-запросы. Вы определяете отдельный контроллер для каждого набора сущностей в службе OData. В этом руководстве мы создадим один контроллер.
В обозревателе решений щелкните правой кнопкой мыши папку Контроллеров. Нажмите кнопку "Добавить " и выберите "Контроллер".
В диалоговом окне "Добавить шаблон" выберите "Контроллер OData для Web API 2 с действиями, использующий Entity Framework".
В диалоговом окне добавления контроллера назовите контроллер ProductsController. Установите флажок "Использовать асинхронные действия контроллера". В раскрывающемся списке "Модель" выберите класс Product.
Нажмите кнопку "Создать контекст данных"... Оставьте имя по умолчанию для типа контекста данных и нажмите кнопку "Добавить".
Нажмите кнопку "Добавить" в диалоговом окне "Добавить контроллер", чтобы добавить контроллер.
Примечание. Если появится сообщение об ошибке с сообщением "Возникла ошибка при получении типа...", убедитесь, что вы создали проект Visual Studio после добавления класса Product. Каркас использует отражение для поиска класса.
Шаблон добавляет в проект два файла кода:
- Products.cs определяет контроллер веб-API, реализующий конечную точку OData.
- ProductServiceContext.cs предоставляет методы для запроса базовой базы данных с помощью Entity Framework.
Добавить EDM и маршрут
В обозревателе решений разверните папку App_Start и откройте файл с именем WebApiConfig.cs. Этот класс содержит код конфигурации для веб-API. Замените этот код следующим образом:
using ProductService.Models;
using System.Web.Http;
using System.Web.Http.OData.Builder;
namespace ProductService
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());
}
}
}
Этот код выполняет следующие две операции:
- Создает модель данных сущностей (EDM) для OData-эндпоинта.
- Добавляет маршрут для конечной точки.
EDM — это абстрактная модель данных. EDM используется для создания документа метаданных и определения URI для службы. ODataConventionModelBuilder создает EDM с помощью набора соглашений об именовании по умолчанию EDM. Для этого подхода требуется наименьший код. Если требуется больше контроля над EDM, можно использовать класс ODataModelBuilder для создания EDM, добавив свойства, ключи и свойства навигации явным образом.
Метод EntitySet добавляет набор сущностей в EDM:
modelBuilder.EntitySet<Product>("Products");
Строка "Products" определяет имя набора сущностей. Имя контроллера должно соответствовать имени набора сущностей. В этом руководстве набор сущностей называется Products, а контроллер называется ProductsController. Если вы назвали набор сущностей ProductSet, вы назовете контроллер ProductSetController. Обратите внимание, что конечная точка может иметь несколько наборов сущностей. Вызов EntitySet<T> для каждого набора сущностей, а затем определите соответствующий контроллер.
Метод MapODataRoute добавляет маршрут для конечной точки OData.
config.Routes.MapODataRoute("ODataRoute", "odata", model);
Первый параметр — понятное имя маршрута. Клиенты вашей службы не видят этого имени. Второй параметр — это префикс URI для конечной точки. Учитывая этот код, URI для набора сущностей Products — http://hostname/odata/Products. Приложение может иметь несколько конечных точек OData. Для каждой конечной точки вызовите MapODataRoute и укажите уникальное имя маршрута и уникальный префикс URI.
Инициализация базы данных (необязательно)
На этом шаге вы будете использовать Entity Framework для заполнения базы данных с некоторыми тестовых данных. Этот шаг является необязательным, но он позволяет сразу протестировать конечную точку OData.
В меню "Сервис" выберите диспетчер пакетов NuGet, а затем консоль диспетчера пакетов. В окне консоли диспетчера пакетов введите следующую команду:
Enable-Migrations
При этом добавляется папка с именем Migrations и файл кода с именем Configuration.cs.
Откройте этот файл и добавьте следующий код в Configuration.Seed метод.
protected override void Seed(ProductService.Models.ProductServiceContext context)
{
// New code
context.Products.AddOrUpdate(new Product[] {
new Product() { ID = 1, Name = "Hat", Price = 15, Category = "Apparel" },
new Product() { ID = 2, Name = "Socks", Price = 5, Category = "Apparel" },
new Product() { ID = 3, Name = "Scarf", Price = 12, Category = "Apparel" },
new Product() { ID = 4, Name = "Yo-yo", Price = 4.95M, Category = "Toys" },
new Product() { ID = 5, Name = "Puzzle", Price = 8, Category = "Toys" },
});
}
В окне консоли диспетчера пакетов введите следующие команды:
Add-Migration Initial
Update-Database
Эти команды создают код, который создает базу данных, а затем выполняет этот код.
Изучение конечной точки OData
В этом разделе мы будем использовать прокси-сервер веб-отладки Fiddler для отправки запросов в конечную точку и проверки сообщений ответа. Это поможет вам понять возможности конечной точки OData.
В Visual Studio нажмите клавишу F5, чтобы начать отладку. По умолчанию Visual Studio открывает браузер http://localhost:*port*, где порт — это номер порта, который настроен в параметрах проекта.
Номер порта можно изменить в параметрах проекта. В обозревателе решений щелкните проект правой кнопкой мыши и выберите пункт "Свойства". В окне свойств выберите "Интернет". Введите номер порта в поле URL-адрес проекта.
Документ службы
Документ службы содержит список наборов сущностей для конечной точки OData. Чтобы получить документ службы, отправьте запрос GET в корневой универсальный код ресурса (URI) службы.
С помощью Fiddler введите следующий URI на вкладке Composer: http://localhost:port/odata/, где port — это номер порта.
Нажмите кнопку "Выполнить ". Fiddler отправляет HTTP-запрос GET в приложение. Вы увидите ответ в списке веб-сеансов. Если все работает, код состояния будет 200.
Дважды щелкните ответ в списке веб-сеансов, чтобы просмотреть сведения об ответном сообщении на вкладке "Инспекторы".
Необработанное сообщение HTTP-ответа должно выглядеть примерно так:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/atomsvc+xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
DataServiceVersion: 3.0
Date: Mon, 23 Sep 2013 17:51:01 GMT
Content-Length: 364
<?xml version="1.0" encoding="utf-8"?>
<service xml:base="http://localhost:60868/odata"
xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">
<workspace>
<atom:title type="text">Default</atom:title>
<collection href="Products">
<atom:title type="text">Products</atom:title>
</collection>
</workspace>
</service></pre>
По умолчанию веб-API возвращает документ службы в формате AtomPub. Чтобы запросить JSON, добавьте следующий заголовок в HTTP-запрос:
Accept: application/json
Теперь http-ответ содержит полезные данные JSON:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
DataServiceVersion: 3.0
Date: Mon, 23 Sep 2013 22:59:28 GMT
Content-Length: 136
{
"odata.metadata":"http://localhost:60868/odata/$metadata","value":[
{
"name":"Products","url":"Products"
}
]
}
Документ метаданных службы
В документе метаданных службы описывается модель данных службы с помощью XML-языка, называемого языком определения концептуальной схемы (CSDL). Документ метаданных показывает структуру данных в службе и может использоваться для создания клиентского кода.
Чтобы получить документ метаданных, отправьте запрос http://localhost:port/odata/$metadataGET. Ниже приведены метаданные конечной точки, показанной в этом руководстве.
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
DataServiceVersion: 3.0
Date: Mon, 23 Sep 2013 23:05:52 GMT
Content-Length: 1086
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:DataServices m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<Schema Namespace="ProductService.Models" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
<EntityType Name="Product">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="Edm.Int32" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
<Property Name="Price" Type="Edm.Decimal" Nullable="false" />
<Property Name="Category" Type="Edm.String" />
</EntityType>
</Schema>
<Schema Namespace="Default" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
<EntityContainer Name="Container" m:IsDefaultEntityContainer="true">
<EntitySet Name="Products" EntityType="ProductService.Models.Product" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Набор сущностей
Чтобы получить набор сущностей продуктов, отправьте GET запрос на http://localhost:port/odata/Products.
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
DataServiceVersion: 3.0
Date: Mon, 23 Sep 2013 23:01:31 GMT
Content-Length: 459
{
"odata.metadata":"http://localhost:60868/odata/$metadata#Products","value":[
{
"ID":1,"Name":"Hat","Price":"15.00","Category":"Apparel"
},{
"ID":2,"Name":"Socks","Price":"5.00","Category":"Apparel"
},{
"ID":3,"Name":"Scarf","Price":"12.00","Category":"Apparel"
},{
"ID":4,"Name":"Yo-yo","Price":"4.95","Category":"Toys"
},{
"ID":5,"Name":"Puzzle","Price":"8.00","Category":"Toys"
}
]
}
Объект
Чтобы получить отдельный продукт, отправьте запрос http://localhost:port/odata/Products(1)GET, где "1" является идентификатором продукта.
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
DataServiceVersion: 3.0
Date: Mon, 23 Sep 2013 23:04:29 GMT
Content-Length: 140
{
"odata.metadata":"http://localhost:60868/odata/$metadata#Products/@Element","ID":1,
"Name":"Hat","Price":"15.00","Category":"Apparel"
}
Форматы сериализации OData
OData поддерживает несколько форматов сериализации:
- Atom Pub (XML)
- JSON "light" (представлено в OData версии 3)
- JSON "подробный" (OData версии 2)
По умолчанию веб-API использует формат AtomPubJSON light.
Чтобы получить формат AtomPub, задайте для заголовка Accept значение application/atom+xml. Ниже приведен пример текста ответа:
<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://localhost:60868/odata" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
<id>http://localhost:60868/odata/Products(1)</id>
<category term="ProductService.Models.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="edit" href="http://localhost:60868/odata/Products(1)" />
<link rel="self" href="http://localhost:60868/odata/Products(1)" />
<title />
<updated>2013-09-23T23:42:11Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:ID m:type="Edm.Int32">1</d:ID>
<d:Name>Hat</d:Name>
<d:Price m:type="Edm.Decimal">15.00</d:Price>
<d:Category>Apparel</d:Category>
</m:properties>
</content>
</entry>
Вы можете заметить один очевидный недостаток формата Atom: он гораздо более многословен, чем JSON light. Однако если у вас есть клиент, который понимает AtomPub, клиент может предпочесть этот формат в формате JSON.
Представлена облегченная версия JSON той же сущности:
{
"odata.metadata":"http://localhost:60868/odata/$metadata#Products/@Element",
"ID":1,
"Name":"Hat",
"Price":"15.00",
"Category":"Apparel"
}
Светлый формат JSON появился в версии 3 протокола OData. Для обратной совместимости клиент может запросить устаревший "verbose"-формат JSON. Чтобы запросить подробный JSON, задайте заголовок Accept в application/json;odata=verbose. Ниже приведена подробная версия:
{
"d":{
"__metadata":{
"id":"http://localhost:18285/odata/Products(1)",
"uri":"http://localhost:18285/odata/Products(1)",
"type":"ProductService.Models.Product"
},"ID":1,"Name":"Hat","Price":"15.00","Category":"Apparel"
}
}
Этот формат передает дополнительные метаданные в тексте отклика, что может добавить значительную нагрузку на весь сеанс. Кроме того, он добавляет уровень косвенности, упаковывая объект в свойство с именем "d".