Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Autor: James Montemagno
Mobilní aplikace můžou komunikovat s back-endovými službami ASP.NET Core. Pokyny k připojení místních webových služeb ze simulátorů iOSu a emulátorů Androidu najdete v tématu Připojení k místním webovým službám z emulátorů Androidu a simulátorů iOS.
Zobrazení nebo stažení ukázkového kódu back-endových služeb
Ukázková nativní mobilní aplikace
Tento kurz ukazuje, jak vytvořit back-endové služby pomocí ASP.NET Core pro podporu nativních mobilních aplikací. Používá .NET MAUI aplikaci jako svého nativního klienta. Ukázka obsahuje projekt služeb webového rozhraní API ASP.NET Core, který tento článek ukazuje, jak sestavit.
Funkce
Aplikace TodoREST podporuje výpis, přidávání, odstraňování a aktualizaci todo položek. Každá položka má ID, název, poznámky a vlastnost označující, jestli se ještě dokončila.
V předchozím příkladu hlavní zobrazení položek uvádí název každé položky a označuje, jestli je hotová se zaškrtnutím.
Klepnutím na ikonu +
přejdete na stránku pro přidání položky:
Klepnutím na položku na hlavní stránce přejdete na stránku pro úpravy, kde se dá upravit název položky, poznámky a nastavení dokončení nebo se dá položka odstranit:
Pokud ho chcete otestovat sami proti aplikaci ASP.NET Core vytvořenou v další části, pokud ji hostujete online, aktualizujte RestUrl
konstantu aplikace. Jinak bude aplikace komunikovat s aplikací ASP.NET Core, která je hostovaná místně na vašem počítači.
Emulátory Androidu neběží na místním počítači a pro komunikaci s ním používají adresu zpětné smyčky (10.0.2.2). Pomocí třídy .NET MAUIDeviceInfo DeviceInfo zjistěte, na kterém operačním systému aplikace běží, aby používala správnou adresu URL.
Přejděte do TodoREST
projektu a otevřete Constants.cs
soubor. Soubor Constants.cs
obsahuje následující konfiguraci.
namespace TodoREST
{
public static class Constants
{
// URL of REST service
//public static string RestUrl = "https://dotnetmauitodorest.azurewebsites.net/api/todoitems/{0}";
// URL of REST service (Android does not use localhost)
// Use http cleartext for local deployment. Change to https for production
public static string LocalhostUrl = DeviceInfo.Platform == DevicePlatform.Android ? "10.0.2.2" : "localhost";
public static string Scheme = "https"; // or http
public static string Port = "5001";
public static string RestUrl = $"{Scheme}://{LocalhostUrl}:{Port}/api/todoitems/{{0}}";
}
}
Webovou službu můžete volitelně nasadit do cloudové služby, jako je Azure, a aktualizovat RestUrl
.
Vytvoření základního projektu ASP.NET
Vytvořte novou webovou aplikaci ASP.NET Core v sadě Visual Studio. Zvolte šablonu webového rozhraní API. Pojmenujte projekt TodoAPI.
Aplikace by měla reagovat na všechny požadavky provedené přes HTTPS na port 5001.
Poznámka:
Spusťte aplikaci přímo, místo prostřednictvím IIS Express. Služba IIS Express ve výchozím nastavení ignoruje jiné než místní požadavky. Spusťte dotnet run z příkazového řádku, nebo zvolte profil aplikace z rozbalovacího seznamu Cíl ladění na panelu nástrojů sady Visual Studio.
Přidejte modelovou třídu, která představuje položky seznamu úkolů. Označte požadovaná pole atributem [Required]
:
using System.ComponentModel.DataAnnotations;
namespace TodoAPI.Models
{
public class TodoItem
{
[Required]
public string ID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Notes { get; set; }
public bool Done { get; set; }
}
}
Metody rozhraní API vyžadují definování pro práci s daty. Použijte stejné rozhraní ITodoRepository
, které ukázka používá:
using TodoAPI.Models;
namespace TodoAPI.Interfaces
{
public interface ITodoRepository
{
bool DoesItemExist(string id);
IEnumerable<TodoItem> All { get; }
TodoItem Find(string id);
void Insert(TodoItem item);
void Update(TodoItem item);
void Delete(string id);
}
}
Pro tuto ukázku implementace úložiště používá pouze soukromou kolekci položek:
using TodoAPI.Interfaces;
using TodoAPI.Models;
namespace TodoAPI.Services
{
public class TodoRepository : ITodoRepository
{
private List<TodoItem> _todoList;
public TodoRepository()
{
InitializeData();
}
public IEnumerable<TodoItem> All
{
get { return _todoList; }
}
public bool DoesItemExist(string id)
{
return _todoList.Any(item => item.ID == id);
}
public TodoItem Find(string id)
{
return _todoList.FirstOrDefault(item => item.ID == id);
}
public void Insert(TodoItem item)
{
_todoList.Add(item);
}
public void Update(TodoItem item)
{
var todoItem = this.Find(item.ID);
var index = _todoList.IndexOf(todoItem);
_todoList.RemoveAt(index);
_todoList.Insert(index, item);
}
public void Delete(string id)
{
_todoList.Remove(this.Find(id));
}
private void InitializeData()
{
_todoList = new List<TodoItem>();
var todoItem1 = new TodoItem
{
ID = "6bb8a868-dba1-4f1a-93b7-24ebce87e243",
Name = "Learn app development",
Notes = "Take Microsoft Learn Courses",
Done = true
};
var todoItem2 = new TodoItem
{
ID = "b94afb54-a1cb-4313-8af3-b7511551b33b",
Name = "Develop apps",
Notes = "Use Visual Studio and Visual Studio Code",
Done = false
};
var todoItem3 = new TodoItem
{
ID = "ecfa6f80-3671-4911-aabe-63cc442c1ecf",
Name = "Publish apps",
Notes = "All app stores",
Done = false,
};
_todoList.Add(todoItem1);
_todoList.Add(todoItem2);
_todoList.Add(todoItem3);
}
}
}
Konfigurujte implementaci v Program.cs
:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddSingleton<TodoAPI.Interfaces.ITodoRepository, TodoAPI.Services.TodoRepository>();
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Vytvoření kontroleru
Přidejte do projektu nový kontroler TodoItemsController. Měl by dědit z ControllerBase.
Route
Přidejte atribut, který označuje, že kontroler zpracovává požadavky provedené v cestách začínajících na api/todoitems
. Token [controller]
v trase se nahradí názvem kontroleru (vynecháním Controller
přípony) a je užitečný zejména pro globální trasy. Přečtěte si další informace o směrování.
Kontrolor vyžaduje ITodoRepository
ke svému fungování; požádejte o instanci tohoto typu prostřednictvím konstruktoru kontroloru. Za běhu je tato instance poskytována pomocí podpory frameworku pro injektování závislostí.
[ApiController]
[Route("api/[controller]")]
public class TodoItemsController : ControllerBase
{
private readonly ITodoRepository _todoRepository;
public TodoItemsController(ITodoRepository todoRepository)
{
_todoRepository = todoRepository;
}
Toto rozhraní API podporuje čtyři různé příkazy HTTP pro provádění operací CRUD (vytvoření, čtení, aktualizace, odstranění) ve zdroji dat. Nejjednodušší z nich je operace čtení, která odpovídá požadavku HTTP GET
.
Testování rozhraní API pomocí curl
Metodu rozhraní API můžete otestovat pomocí různých nástrojů. Pro účely tohoto kurzu se používají následující opensourcové nástroje příkazového řádku:
-
curl: Přenáší data pomocí různých protokolů, včetně HTTP a HTTPS. Curl se používá v tomto kurzu k volání rozhraní API pomocí metod
GET
HTTP ,POST
,PUT
aDELETE
. - jq: Procesor JSON použitý v tomto kurzu k formátování dat JSON tak, aby se snadno četl z odpovědi rozhraní API.
Nainstalujte curl a jq
Curl je předinstalovaný v systému macOS a používá se přímo v aplikaci terminálu macOS. Další informace o instalaci curl naleznete na oficiálních stránkách curl.
jq lze nainstalovat z Homebrew z terminálu:
Nainstalujte Homebrew, pokud ještě není nainstalovaný, pomocí následujícího příkazu:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Postupujte podle pokynů uvedených instalačním programem.
Nainstalujte jq pomocí Homebrew pomocí následujícího příkazu:
brew install jq
Další informace o instalaci Homebrew a jq naleznete v tématu Homebrew a jq.
Čtení položek
Žádost o seznam položek se provádí s požadavkem GET na metodu List
. Atribut [HttpGet]
metody List
označuje, že tato akce by měla zpracovávat pouze požadavky GET. Trasa pro tuto akci je trasa zadaná v kontroleru. Název akce nemusíte nutně používat jako součást trasy. Stačí zajistit, aby každá akce měla jedinečnou a jednoznačnou trasu. Atributy směrování je možné použít na úrovni kontroleru i metody k sestavení konkrétních tras.
[HttpGet]
public IActionResult List()
{
return Ok(_todoRepository.All);
}
V terminálu zavolejte následující příkaz curl:
curl -v -X GET 'https://localhost:5001/api/todoitems/' | jq
Předchozí příkaz curl obsahuje následující komponenty:
-
-v
: Aktivuje podrobný režim, poskytuje podrobné informace o odpovědi HTTP a je užitečný pro testování rozhraní API a řešení potíží. -
-X GET
: Určuje použití metody HTTPGET
pro požadavek. I když curl může často odvodit zamýšlenou metodu HTTP, tato možnost z něj dělá explicitní. -
'https://localhost:5001/api/todoitems/'
: Toto je cílová adresa URL požadavku. V tomto případě se jedná o REST koncový bod rozhraní API. -
| jq
: Tento segment nesouvisí přímo s curl. Trubka|
je shellový operátor, který přebírá výstup z příkazu vlevo a posílá ho do příkazu vpravo.jq
je procesor JSON příkazového řádku. I když to není povinné,jq
usnadní čtení vrácených dat JSON.
Metoda List
vrátí kód odpovědi 200 OK a všechny položky Todo serializované jako JSON.
[
{
"id": "6bb8a868-dba1-4f1a-93b7-24ebce87e243",
"name": "Learn app development",
"notes": "Take Microsoft Learn Courses",
"done": true
},
{
"id": "b94afb54-a1cb-4313-8af3-b7511551b33b",
"name": "Develop apps",
"notes": "Use Visual Studio and Visual Studio Code",
"done": false
},
{
"id": "ecfa6f80-3671-4911-aabe-63cc442c1ecf",
"name": "Publish apps",
"notes": "All app stores",
"done": false
}
]
Vytváření položek
Podle konvence se vytváření nových datových položek mapuje na příkaz HTTP POST
. Metoda Create
má atribut [HttpPost]
aplikovaný na ni a přijímá instanci TodoItem
. Vzhledem k tomu, že argument item
je předán v těle POST, tento parametr určuje [FromBody]
atribut.
Uvnitř metody je položka zkontrolována platnost a předchozí existence v úložišti dat, a pokud nedojde k žádným problémům, přidá se pomocí úložiště. Kontrola ModelState.IsValid
provádí ověření modelu a měla by být provedena v každé metodě rozhraní API, která přijímá uživatelský vstup.
[HttpPost]
public IActionResult Create([FromBody]TodoItem item)
{
try
{
if (item == null || !ModelState.IsValid)
{
return BadRequest(ErrorCode.TodoItemNameAndNotesRequired.ToString());
}
bool itemExists = _todoRepository.DoesItemExist(item.ID);
if (itemExists)
{
return StatusCode(StatusCodes.Status409Conflict, ErrorCode.TodoItemIDInUse.ToString());
}
_todoRepository.Insert(item);
}
catch (Exception)
{
return BadRequest(ErrorCode.CouldNotCreateItem.ToString());
}
return Ok(item);
}
Ukázka používá enum
, který obsahuje kódy chyb, jež se předávají mobilnímu klientovi.
public enum ErrorCode
{
TodoItemNameAndNotesRequired,
TodoItemIDInUse,
RecordNotFound,
CouldNotCreateItem,
CouldNotUpdateItem,
CouldNotDeleteItem
}
V terminálu otestujte přidání nových položek voláním následujícího příkazu curl pomocí POST
příkazu a zadáním nového objektu ve formátu JSON v textu požadavku.
curl -v -X POST 'https://localhost:5001/api/todoitems/' \
--header 'Content-Type: application/json' \
--data '{
"id": "6bb8b868-dba1-4f1a-93b7-24ebce87e243",
"name": "A Test Item",
"notes": "asdf",
"done": false
}' | jq
Předchozí příkaz curl obsahuje následující možnosti:
-
--header 'Content-Type: application/json'
: Nastaví hlavičkuContent-Type
naapplication/json
označující, že tělo požadavku obsahuje data JSON. -
--data '{...}'
: Odešle zadaná data v těle požadavku.
Metoda vrátí nově vytvořenou položku v odpovědi.
Aktualizace položek
Úpravy záznamů se dosahuje pomocí požadavků HTTP PUT
. Kromě této změny Edit
je metoda téměř identická s Create
. Pokud se záznam nenajde, akce Edit
vrátí odpověď NotFound
(404).
[HttpPut]
public IActionResult Edit([FromBody] TodoItem item)
{
try
{
if (item == null || !ModelState.IsValid)
{
return BadRequest(ErrorCode.TodoItemNameAndNotesRequired.ToString());
}
var existingItem = _todoRepository.Find(item.ID);
if (existingItem == null)
{
return NotFound(ErrorCode.RecordNotFound.ToString());
}
_todoRepository.Update(item);
}
catch (Exception)
{
return BadRequest(ErrorCode.CouldNotUpdateItem.ToString());
}
return NoContent();
}
Chcete-li testovat pomocí curl, změňte sloveso na PUT
. Zadejte aktualizovaná data objektu v textu požadavku.
curl -v -X PUT 'https://localhost:5001/api/todoitems/' \
--header 'Content-Type: application/json' \
--data '{
"id": "6bb8b868-dba1-4f1a-93b7-24ebce87e243",
"name": "A Test Item",
"notes": "asdf",
"done": true
}' | jq
Tato metoda vrátí NoContent
odpověď (204), pokud je úspěšná, z důvodu konzistence s již existujícím API.
Odstraňování položek
Odstraňování záznamů se provádí odesláním DELETE
požadavku na službu a předáním ID položky, která se má odstranit. Stejně jako u aktualizací, požadavky na položky, které neexistují, obdrží NotFound
odpovědi. V opačném případě úspěšný požadavek vrátí odpověď (204) NoContent
.
[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
try
{
var item = _todoRepository.Find(id);
if (item == null)
{
return NotFound(ErrorCode.RecordNotFound.ToString());
}
_todoRepository.Delete(id);
}
catch (Exception)
{
return BadRequest(ErrorCode.CouldNotDeleteItem.ToString());
}
return NoContent();
}
Otestujte pomocí nástroje curl změnou příkazu HTTP na DELETE
a připojením ID datového objektu, který se má odstranit na konci adresy URL. V textu požadavku se nevyžaduje nic.
curl -v -X DELETE 'https://localhost:5001/api/todoitems/6bb8b868-dba1-4f1a-93b7-24ebce87e243'
Prevence nadměrného zveřejňování příspěvků
V současné době ukázková aplikace zveřejňuje celý TodoItem
objekt. Produkční aplikace obvykle omezují vstupní a vrácená data pomocí podmnožiny modelu. Z tohoto důvodu existuje několik důvodů a zabezpečení je hlavním důvodem. Podmnožina modelu se obvykle označuje jako objekt pro přenos dat (DTO), vstupní model nebo model zobrazení.
DTO se používá v tomto článku.
DTO lze použít k:
- Zabránit nadměrnému zveřejňování.
- Skryjte vlastnosti, které klienti nemají zobrazit.
- Pro snížení velikosti datové části vynechejte některé vlastnosti.
- Zplošťte grafy objektů, které obsahují vnořené objekty. Grafy plochých objektů můžou být pro klienty pohodlnější.
Abychom předvedli přístup DTO, podívejte se na Prevenci nadměrného zadávání dat.
Běžné konvence webového rozhraní API
Při vývoji back-endových služeb pro vaši aplikaci budete chtít přijít s konzistentní sadou konvencí nebo zásad pro řešení průřezových obav. Například ve službě zobrazené dříve byly žádosti o konkrétní záznamy, které nebyly nalezeny, obdržely NotFound
odpověď, nikoli BadRequest
odpověď. Podobně příkazy zadané do této služby, které zahrnovaly typy navázané na model, vždy zkontrolovaly ModelState.IsValid
a vrátily BadRequest
pro neplatné typy modelu.
Jakmile identifikujete společnou zásadu pro vaše rozhraní API, můžete ji obvykle zapouzdřovat do filtru. Přečtěte si další informace o zapouzdření běžných zásad rozhraní API v aplikacích ASP.NET Core MVC.