Vytvoření koncového bodu OData v3 pomocí webového rozhraní API 2
Mike Wasson
OData (Open Data Protocol) je protokol pro přístup k datům pro web. OData poskytuje jednotný způsob strukturování dat, dotazování dat a manipulaci s datovou sadou prostřednictvím operací CRUD (vytvoření, čtení, aktualizace a odstranění). OData podporuje formáty AtomPub (XML) i JSON. OData také definuje způsob, jak zveřejnit metadata o datech. Klienti můžou pomocí metadat zjistit informace o typu a relace pro sadu dat.
ASP.NET webové rozhraní API usnadňuje vytvoření koncového bodu OData pro datovou sadu. Můžete přesně určit, které operace OData koncový bod podporuje. Můžete hostovat několik koncových bodů OData společně s jinými koncovými body než OData. Máte plnou kontrolu nad datovým modelem, back-endovou obchodní logikou a datovou vrstvou.
Verze softwaru použité v tomto kurzu
- Visual Studio 2013
- Webové rozhraní API 2
- OData verze 3
- Entity Framework 6
- Fiddler Web Debugging Proxy (volitelné)
Podpora webového rozhraní API OData byla přidána v aktualizaci ASP.NET and Web Tools 2012.2. Tento kurz ale používá generování uživatelského rozhraní, které bylo přidáno v Visual Studio 2013.
V tomto kurzu vytvoříte jednoduchý koncový bod OData, na který se můžou klienti dotazovat. Pro koncový bod také vytvoříte klienta jazyka C#. Po dokončení tohoto kurzu se v další sadě kurzů dozvíte, jak přidat další funkce, včetně vztahů mezi entitami, akcí a $expand/$select.
- Vytvoření projektu sady Visual Studio
- Přidání modelu entity
- Přidání kontroleru OData
- Přidání EDM a trasy
- Nasypat databázi (volitelné)
- Zkoumání koncového bodu OData
- Formáty serializace OData
Vytvoření projektu sady Visual Studio
V tomto kurzu vytvoříte koncový bod OData, který podporuje základní operace CRUD. Koncový bod zveřejní jeden prostředek, seznam produktů. V pozdějších kurzech přidají další funkce.
Spusťte Visual Studio a na stránce Start vyberte Nový projekt . Nebo v nabídce File (Soubor ) vyberte New (Nový ) a pak Project (Projekt).
V podokně Šablony vyberte Nainstalované šablony a rozbalte uzel Visual C#. V části Visual C# vyberte Web. Vyberte šablonu webové aplikace ASP.NET .
V dialogovém okně Nový projekt ASP.NET vyberte šablonu Prázdný . V části Přidat složky a základní odkazy pro... zkontrolujte webové rozhraní API. Klikněte na OK.
Přidání modelu entity
Model je objekt, který představuje data ve vaší aplikaci. Pro účely tohoto kurzu potřebujeme model, který představuje produkt. Model odpovídá našemu typu entity OData.
V Průzkumník řešení klikněte pravým tlačítkem na složku Modely. V místní nabídce vyberte Přidat a pak vyberte Třída.
V dialogovém okně Přidat novou položku pojmenujte třídu "Product".
Poznámka
Podle konvence jsou třídy modelu umístěny ve složce Modely. Tuto konvenci nemusíte dodržovat ve svých vlastních projektech, ale použijeme ji pro tento kurz.
Do souboru Product.cs přidejte následující definici třídy:
public class Product
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
Vlastnost ID bude klíč entity. Klienti se můžou dotazovat na produkty podle ID. Toto pole bude také primárním klíčem v back-endové databázi.
Sestavte projekt. V dalším kroku použijeme některé generování uživatelského rozhraní sady Visual Studio, které pomocí reflexe najde typ produktu.
Přidání kontroleru OData
Kontroler je třída, která zpracovává požadavky HTTP. Pro každou sadu entit ve službě OData definujete samostatný kontroler. V tomto kurzu vytvoříme jeden kontroler.
V Průzkumník řešení klikněte pravým tlačítkem na složku Kontrolery. Vyberte Přidat a pak vyberte Kontroler.
V dialogovém okně Přidat generování uživatelského rozhraní vyberte Kontroler OData webového rozhraní API 2 s akcemi pomocí Entity Frameworku.
V dialogovém okně Přidat kontroler pojmenujte kontroler ProductsController. Zaškrtněte políčko Použít akce asynchronního kontroleru. V rozevíracím seznamu Model vyberte Třídu Product.
Klikněte na tlačítko Nový kontext dat. Ponechte výchozí název pro typ kontextu dat a klikněte na Přidat.
Kliknutím na Přidat v dialogovém okně Přidat kontroler přidejte kontroler.
Poznámka: Pokud se zobrazí chybová zpráva Typu došlo k chybě, ujistěte se, že jste po přidání třídy Product vytvořili projekt sady Visual Studio. Generování používá reflexi k vyhledání třídy.
Generování přidá do projektu dva soubory kódu:
- Products.cs definuje kontroler webového rozhraní API, který implementuje koncový bod OData.
- ProductServiceContext.cs poskytuje metody pro dotazování podkladové databáze pomocí Entity Frameworku.
Přidání EDM a trasy
V Průzkumník řešení rozbalte složku App_Start a otevřete soubor s názvem WebApiConfig.cs. Tato třída obsahuje konfigurační kód pro webové rozhraní API. Nahraďte tento kód následujícím kódem:
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());
}
}
}
Tento kód dělá dvě věci:
- Vytvoří model EDM (Entity Data Model) pro koncový bod OData.
- Přidá trasu pro koncový bod.
EDM je abstraktní model dat. EDM slouží k vytvoření dokumentu metadat a definování identifikátorů URI pro službu. ODataConventionModelBuilder vytvoří EDM pomocí sady výchozích konvencí vytváření názvů EDM. Tento přístup vyžaduje nejmenší kód. Pokud chcete mít větší kontrolu nad EDM, můžete použít třídu ODataModelBuilder k vytvoření EDM přidáním vlastností, klíčů a navigačních vlastností explicitně.
Metoda EntitySet přidá sadu entit do EDM:
modelBuilder.EntitySet<Product>("Products");
Řetězec Products definuje název sady entit. Název kontroleru se musí shodovat s názvem sady entit. V tomto kurzu má sada entit název Products (Produkty) a kontroler má název ProductsController
. Pokud jste sadu entit pojmenovali ProductSet, pojmenovali byste kontroler ProductSetController
. Všimněte si, že koncový bod může mít více sad entit. Zavolejte EntitySet<T> pro každou sadu entit a pak definujte odpovídající kontroler.
Metoda MapODataRoute přidá trasu pro koncový bod OData.
config.Routes.MapODataRoute("ODataRoute", "odata", model);
První parametr je popisný název trasy. Klienti vaší služby tento název nevidí. Druhým parametrem je předpona identifikátoru URI koncového bodu. Vzhledem k tomuto kódu je identifikátor URI sady entit Products http:// hostname/odata/Products. Vaše aplikace může mít více než jeden koncový bod OData. Pro každý koncový bod zavolejte MapODataRoute a zadejte jedinečný název trasy a jedinečnou předponu identifikátoru URI.
Nasypat databázi (volitelné)
V tomto kroku použijete Entity Framework k nasypat databázi některými testovacími daty. Tento krok je volitelný, ale umožňuje okamžitě otestovat koncový bod OData.
V nabídce Nástroje vyberte Správce balíčků NuGet a pak vyberte Konzola Správce balíčků. V okně konzoly Správce balíčků zadejte následující příkaz:
Enable-Migrations
Tím se přidá složka s názvem Migrace a soubor kódu s názvem Configuration.cs.
Otevřete tento soubor a přidejte do Configuration.Seed
metody následující kód.
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" },
});
}
V okně konzoly Správce balíčků zadejte následující příkazy:
Add-Migration Initial
Update-Database
Tyto příkazy vygenerují kód, který vytvoří databázi, a pak tento kód spustí.
Zkoumání koncového bodu OData
V této části použijeme proxy fiddlerového ladění webu k odesílání požadavků do koncového bodu a prozkoumání zpráv odpovědí. To vám pomůže pochopit možnosti koncového bodu OData.
V sadě Visual Studio spusťte ladění stisknutím klávesy F5. Visual Studio ve výchozím nastavení otevře prohlížeč na http://localhost:*port*
, kde port je číslo portu nakonfigurované v nastavení projektu.
Číslo portu můžete změnit v nastavení projektu. V Průzkumník řešení klikněte pravým tlačítkem na projekt a vyberte Vlastnosti. V okně vlastností vyberte Web. Zadejte číslo portu v části Adresa URL projektu.
Dokument služby
Dokument služby obsahuje seznam sad entit pro koncový bod OData. Pokud chcete získat dokument služby, odešlete požadavek GET na kořenový identifikátor URI služby.
Pomocí nástroje Fiddler zadejte na kartě Composer následující identifikátor URI: http://localhost:port/odata/
, kde port je číslo portu.
Klikněte na tlačítko Provést. Fiddler odešle do vaší aplikace požadavek HTTP GET. Odpověď by se měla zobrazit v seznamu Webových relací. Pokud všechno funguje, stavový kód bude 200.
Poklikáním na odpověď v seznamu Webové relace zobrazíte podrobnosti o zprávě odpovědi na kartě Inspektory.
Nezpracovaná zpráva odpovědi HTTP by měla vypadat nějak takto:
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>
Ve výchozím nastavení vrátí webové rozhraní API dokument služby ve formátu AtomPub. Pokud chcete požádat o JSON, přidejte do požadavku HTTP následující hlavičku:
Accept: application/json
Odpověď HTTP teď obsahuje datovou část 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"
}
]
}
Dokument metadat služby
Dokument metadat služby popisuje datový model služby pomocí jazyka XML označovaného jako CSDL (Conceptual Schema Definition Language). Dokument metadat ukazuje strukturu dat ve službě a dá se použít ke generování klientského kódu.
Pokud chcete získat dokument metadat, odešlete požadavek GET na adresu http://localhost:port/odata/$metadata
. Tady jsou metadata koncového bodu uvedená v tomto kurzu.
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>
Sada entit
Pokud chcete získat sadu entit Products, odešlete požadavek GET na adresu 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"
}
]
}
Entita
Pokud chcete získat jednotlivý produkt, odešlete žádost GET na http://localhost:port/odata/Products(1)
adresu , kde "1" je ID produktu.
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"
}
Formáty serializace OData
OData podporuje několik formátů serializace:
- Atom Pub (XML)
- Json "light" (zavedeno v OData v3)
- Verbose JSON (OData v2)
Ve výchozím nastavení používá webové rozhraní API "light" formát AtomPubJSON.
Pokud chcete získat formát AtomPub, nastavte hlavičku Accept na application/atom+xml. Tady je příklad textu odpovědi:
<?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>
Můžete vidět jednu zjevnou nevýhodu formátu Atom: Je mnohem podrobnější než světlo JSON. Pokud ale máte klienta, který rozumí AtomPub, může dát přednost ho formátu před JSON.
Tady je light verze JSON stejné entity:
{
"odata.metadata":"http://localhost:60868/odata/$metadata#Products/@Element",
"ID":1,
"Name":"Hat",
"Price":"15.00",
"Category":"Apparel"
}
Světlý formát JSON byl zaveden ve verzi 3 protokolu OData. Pro zpětnou kompatibilitu může klient požádat o starší "podrobný" formát JSON. Pokud chcete požádat o podrobný kód JSON, nastavte hlavičku Accept na application/json;odata=verbose
. Tady je podrobná verze:
{
"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"
}
}
Tento formát vyjadřuje více metadat v textu odpovědi, což může výrazně náležet na celou relaci. Také přidává úroveň nepřímých dat zabalením objektu do vlastnosti s názvem "d".