Povolení operací CRUD ve webovém rozhraní API ASP.NET 1

Mike Wasson

Stažení dokončeného projektu

V tomto kurzu se dozvíte, jak podporovat operace CRUD ve službě HTTP pomocí ASP.NET webového rozhraní API pro ASP.NET 4.x.

Verze softwaru použité v kurzu

  • Visual Studio 2012
  • Webové rozhraní API 1 (funguje také s webovým rozhraním API 2)

CRUD je zkratka pro vytvoření, čtení, aktualizaci a odstranění, což jsou čtyři základní databázové operace. Mnoho služeb HTTP také modeluje operace CRUD prostřednictvím rozhraní REST nebo rozhraní API podobných REST.

V tomto kurzu vytvoříte velmi jednoduché webové rozhraní API pro správu seznamu produktů. Každý produkt bude obsahovat název, cenu a kategorii (například "hračky" nebo "hardware") a ID produktu.

Rozhraní API pro produkty zveřejní následující metody.

Akce Metoda HTTP Relativní identifikátor URI
Získání seznamu všech produktů GET /api/products
Získání produktu podle ID GET /api/products/id
Získání produktu podle kategorie GET /api/products?category=category
Vytvoření nového produktu POST /api/products
Aktualizace produktu PUT /api/products/id
Odstranění produktu DELETE /api/products/id

Všimněte si, že některé identifikátory URI obsahují ID produktu v cestě. Pokud například chcete získat produkt, jehož ID je 28, klient odešle požadavek GET pro http://hostname/api/products/28.

Zdroje informací

Rozhraní API produktů definuje identifikátory URI pro dva typy prostředků:

Prostředek Identifikátor URI
Seznam všech produktů. /api/products
Jednotlivý produkt. /api/products/id

Metody

Čtyři hlavní metody HTTP (GET, PUT, POST a DELETE) je možné mapovat na operace CRUD následujícím způsobem:

  • Get načte reprezentaci prostředku se zadaným identifikátorem URI. Get by neměl mít na serveru žádné vedlejší účinky.
  • PUT aktualizuje prostředek se zadaným identifikátorem URI. PUT lze také použít k vytvoření nového prostředku se zadaným identifikátorem URI, pokud server umožňuje klientům zadat nové identifikátory URI. Pro účely tohoto kurzu rozhraní API nebude podporovat vytváření prostřednictvím PUT.
  • POST vytvoří nový prostředek. Server přiřadí identifikátor URI novému objektu a vrátí tento identifikátor URI jako součást zprávy odpovědi.
  • Delete odstraní prostředek se zadaným identifikátorem URI.

Poznámka: Metoda PUT nahrazuje celou entitu produktu. To znamená, že se očekává, že klient odešle kompletní reprezentaci aktualizovaného produktu. Pokud chcete podporovat částečné aktualizace, je vhodnější metoda PATCH. Tento kurz neimplementuje patch.

Vytvoření nového projektu webového rozhraní API

Začněte spuštěním sady Visual Studio a na úvodní stránce vyberte Nový projekt. Nebo v nabídce Soubor vyberte Nový a pak Projekt.

V podokně Šablony vyberte Nainstalované šablony a rozbalte uzel Visual C# . V části Visual C# vyberte Web. V seznamu šablon projektů vyberte ASP.NET webová aplikace MVC 4. Pojmenujte projekt ProductStore a klikněte na OK.

Snímek obrazovky s oknem nového projektu s možnostmi nabídky a zvýrazněnou cestou k vytvoření webové aplikace A S P dot NET M V C 4

V dialogovém okně Nový projekt ASP.NET MVC 4 vyberte Webové rozhraní API a klikněte na OK.

Snímek obrazovky s novým projektem A S P dot NET, který zobrazuje obrázky dostupných šablon v rámečku a modře zvýrazněnou šablonu Webové žádosti o přijetí prostředků

Přidání modelu

Model je objekt, který představuje data ve vaší aplikaci. Ve webovém rozhraní API ASP.NET můžete jako modely použít objekty CLR se silnými typy, které se pro klienta automaticky serializují do XML nebo JSON.

Pro rozhraní API ProductStore se naše data skládají z produktů, takže vytvoříme novou třídu s názvem Product.

Pokud Průzkumník řešení ještě nevidíte, klikněte na nabídku Zobrazení a vyberte Průzkumník řešení. 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. Pojmenujte třídu "Product".

Snímek obrazovky s nabídkou průzkumníka řešení se zvýrazněným výběrem modelů, aby se zobrazila další nabídka pro výběr možnosti přidat třídu

Do třídy přidejte následující vlastnosti Product .

namespace ProductStore.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}

Přidání úložiště

Potřebujeme uložit kolekci produktů. Je vhodné oddělit kolekci od implementace služby. Tímto způsobem můžeme změnit záložní úložiště bez přepsání třídy služby. Tento typ návrhu se nazývá vzor úložiště . Začněte definováním obecného rozhraní pro úložiště.

V Průzkumník řešení klikněte pravým tlačítkem na složku Modely. Vyberte Přidat a pak vyberte Nová položka.

Snímek obrazovky s nabídkou Průzkumníka řešení, která zvýrazní možnost modelů a zobrazí nabídku pro přidání nové položky

V podokně Šablony vyberte Nainstalované šablony a rozbalte uzel C#. V části C# vyberte Kód. V seznamu šablon kódu vyberte Rozhraní. Rozhraní pojmenujte "IProductRepository".

Snímek obrazovky s podoknem šablon zobrazující nabídku nainstalovaných šablon, která zvýrazňuje možnosti kódu a rozhraní šedě

Přidejte následující implementaci:

namespace ProductStore.Models
{
    public interface IProductRepository
    {
        IEnumerable<Product> GetAll();
        Product Get(int id);
        Product Add(Product item);
        void Remove(int id);
        bool Update(Product item);
    }
}

Teď do složky Models přidejte další třídu s názvem ProductRepository. Tato třída implementuje IProductRepository rozhraní . Přidejte následující implementaci:

namespace ProductStore.Models
{
    public class ProductRepository : IProductRepository
    {
        private List<Product> products = new List<Product>();
        private int _nextId = 1;

        public ProductRepository()
        {
            Add(new Product { Name = "Tomato soup", Category = "Groceries", Price = 1.39M });
            Add(new Product { Name = "Yo-yo", Category = "Toys", Price = 3.75M });
            Add(new Product { Name = "Hammer", Category = "Hardware", Price = 16.99M });
        }

        public IEnumerable<Product> GetAll()
        {
            return products;
        }

        public Product Get(int id)
        {
            return products.Find(p => p.Id == id);
        }

        public Product Add(Product item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            item.Id = _nextId++;
            products.Add(item);
            return item;
        }

        public void Remove(int id)
        {
            products.RemoveAll(p => p.Id == id);
        }

        public bool Update(Product item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            int index = products.FindIndex(p => p.Id == item.Id);
            if (index == -1)
            {
                return false;
            }
            products.RemoveAt(index);
            products.Add(item);
            return true;
        }
    }
}

Úložiště uchovává seznam v místní paměti. To je v případě kurzu v pořádku, ale ve skutečné aplikaci byste data ukládali externě, buď do databáze, nebo do cloudového úložiště. Model úložiště usnadní pozdější změnu implementace.

Přidání kontroleru webového rozhraní API

Pokud jste pracovali s ASP.NET MVC, pak už ovladače znáte. Ve webovém rozhraní API ASP.NET je kontroler třída, která zpracovává požadavky HTTP z klienta. Průvodce novým projektem pro vás při vytváření projektu vytvořil dva kontrolery. Pokud je chcete zobrazit, rozbalte složku Kontrolery v Průzkumník řešení.

  • HomeController je tradiční kontroler ASP.NET MVC. Zodpovídá za obsluhu stránek HTML webu a nesouvisí přímo s naším webovým rozhraním API.
  • ValuesController je ukázkový kontroler WebAPI.

Pokračujte a odstraňte ValuesController tak, že kliknete pravým tlačítkem na soubor v Průzkumník řešení a vyberete Odstranit. Teď následujícím způsobem přidejte nový kontroler:

V Průzkumník řešení klikněte pravým tlačítkem na složku Kontrolery. Vyberte Přidat a pak vyberte Kontroler.

Snímek obrazovky s nabídkou Průzkumníka řešení se zvýrazněnou kategorií kontrolerů, která přináší další nabídku se zvýrazněnou cestou k přidání kontroleru

V průvodci Přidat kontroler pojmenujte kontroler ProductsController. V rozevíracím seznamu Šablona vyberte Prázdný kontroler rozhraní API. Pak klikněte na Přidat.

Snímek obrazovky s oknem přidat kontroler, ve kterém je pole s názvem kontroleru pro zadání názvu a rozevírací seznam šablon v části Možnosti generování uživatelského rozhraní

Poznámka

Ovladače není nutné umisťovat do složky s názvem Controllers. Název složky není důležitý. je to jednoduše pohodlný způsob, jak uspořádat zdrojové soubory.

Průvodce přidáním kontroleru vytvoří ve složce Kontrolery soubor s názvem ProductsController.cs. Pokud tento soubor ještě není otevřený, otevřete ho poklikáním. Přidejte následující příkaz using :

using ProductStore.Models;

Přidejte pole, které obsahuje instanci IProductRepository .

public class ProductsController : ApiController
{
    static readonly IProductRepository repository = new ProductRepository();
}

Poznámka

Volání new ProductRepository() v kontroleru není nejlepší návrh, protože spojuje kontroler s konkrétní implementací .IProductRepository Lepší přístup najdete v tématu Použití překladače závislostí webového rozhraní API.

Získání prostředku

Rozhraní API ProductStore zveřejní několik akcí čtení jako metody HTTP GET. Každá akce bude odpovídat metodě ve ProductsController třídě .

Akce Metoda HTTP Relativní identifikátor URI
Získání seznamu všech produktů GET /api/products
Získání produktu podle ID GET /api/products/id
Získání produktu podle kategorie GET /api/products?category=category

Pokud chcete získat seznam všech produktů, přidejte do třídy tuto metodu ProductsController :

public class ProductsController : ApiController
{
    public IEnumerable<Product> GetAllProducts()
    {
        return repository.GetAll();
    }
    // ....
}

Název metody začíná na Get, takže se podle konvence mapuje na požadavky GET. Vzhledem k tomu, že metoda nemá žádné parametry, mapuje se na identifikátor URI, který v cestě neobsahuje segment "id" .

Pokud chcete získat produkt podle ID, přidejte do třídy tuto metodu ProductsController :

public Product GetProduct(int id)
{
    Product item = repository.Get(id);
    if (item == null)
    {
        throw new HttpResponseException(HttpStatusCode.NotFound); 
    }
    return item;
}

Tento název metody také začíná na Get, ale metoda má parametr s názvem id. Tento parametr je mapován na segment "id" cesty URI. Rozhraní ASP.NET Web API automaticky převede ID na správný datový typ (int) parametru.

GetProduct Metoda vyvolá výjimku typu HttpResponseException , pokud id není platné. Tato výjimka se v rámci přeloží na chybu 404 (Nenalezena).

Nakonec přidejte metodu pro vyhledání produktů podle kategorie:

public IEnumerable<Product> GetProductsByCategory(string category)
{
    return repository.GetAll().Where(
        p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase));
}

Pokud má identifikátor URI požadavku řetězec dotazu, webové rozhraní API se pokusí spárovat parametry dotazu s parametry v metodě kontroleru. Proto se identifikátor URI ve formátu "api/products?category=category" namapuje na tuto metodu.

Vytvoření prostředku

V dalším kroku přidáme do třídy metodu ProductsController pro vytvoření nového produktu. Tady je jednoduchá implementace metody:

// Not the final implementation!
public Product PostProduct(Product item)
{
    item = repository.Add(item);
    return item;
}

Všimněte si dvou věcí o této metodě:

  • Název metody začíná na "Post...". Pokud chcete vytvořit nový produkt, klient odešle požadavek HTTP POST.
  • Metoda přebírá parametr typu Product. Ve webovém rozhraní API se parametry se složitými typy deserializují z textu požadavku. Proto očekáváme, že klient odešle serializovanou reprezentaci objektu produktu ve formátu XML nebo JSON.

Tato implementace bude fungovat, ale není úplně dokončená. V ideálním případě bychom chtěli, aby odpověď HTTP obsahovala následující:

  • Kód odpovědi: Ve výchozím nastavení architektura webového rozhraní API nastaví stavový kód odpovědi na 200 (OK). Ale podle protokolu HTTP/1.1, když požadavek POST vede k vytvoření prostředku, server by měl odpovědět se stavem 201 (Vytvořeno).
  • Umístění: Když server vytvoří prostředek, měl by v hlavičce Location odpovědi obsahovat identifikátor URI nového prostředku.

ASP.NET webové rozhraní API usnadňuje manipulaci se zprávou odpovědi HTTP. Tady je vylepšená implementace:

public HttpResponseMessage PostProduct(Product item)
{
    item = repository.Add(item);
    var response = Request.CreateResponse<Product>(HttpStatusCode.Created, item);

    string uri = Url.Link("DefaultApi", new { id = item.Id });
    response.Headers.Location = new Uri(uri);
    return response;
}

Všimněte si, že návratový typ metody je nyní HttpResponseMessage. Vrácením zprávy HttpResponseMessage místo Product můžeme řídit podrobnosti o zprávě odpovědi HTTP, včetně stavového kódu a hlavičky Location.

CreateResponse Metoda vytvoří HttpResponseMessage a automaticky zapíše serializované reprezentace Product objektu do těla zprávy odpovědi.

Poznámka

Tento příklad neověřuje Product. Informace o ověřování modelu najdete v tématu Ověření modelu ve webovém rozhraní API ASP.NET.

Aktualizace prostředku

Aktualizace produktu pomocí PUT je jednoduchá:

public void PutProduct(int id, Product product)
{
    product.Id = id;
    if (!repository.Update(product))
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }
}

Název metody začíná na Put..., takže ho webové rozhraní API odpovídá požadavkům PUT. Metoda přijímá dva parametry: ID produktu a aktualizovaný produkt. Parametr id je převzat z cesty URI a parametr produktu je deserializován z textu požadavku. Ve výchozím nastavení rozhraní ASP.NET Web API přebírá jednoduché typy parametrů z trasy a komplexní typy z textu požadavku.

Odstranění prostředku

Pokud chcete odstranit prostředek, definujte možnost Odstranit... Metoda.

public void DeleteProduct(int id)
{
    Product item = repository.Get(id);
    if (item == null)
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }

    repository.Remove(id);
}

Pokud je požadavek DELETE úspěšný, může vrátit stav 200 (OK) s entitou-tělo, které popisuje stav; stav 202 (Přijato), pokud odstranění stále čeká na vyřízení; nebo stav 204 (žádný obsah) bez těla entity. V tomto případě DeleteProduct má metoda návratový void typ, takže ASP.NET Webové rozhraní API ho automaticky přeloží na stavový kód 204 (Bez obsahu).