Kapitola 5: Vytváření a publikování webového rozhraní API v Azure
Poté, co zjistili, že data pro aplikaci techniků by měla být získávána ze stávajících systémů prostřednictvím webového rozhraní API, Maria a Kiana společně určují, které informace jsou přesně potřebné a v jakém formátu. Kiana poté vytvoří webovou aplikaci, která zpřístupní příslušné webové rozhraní API a zajistí jeho hostování v Azure. Aplikace se může připojit k Azure odkudkoli, kde je bezdrátové připojení.
Definování operací webového API: Správa inventáře v terénu
Obrazovka Procházet aplikace Field Inventory Management zobrazuje seznam dílů pro kotle a klimatizační systémy (dále jen díly kotle). Obrazovka Podrobnosti umožňuje technikovi zobrazit více informací o vybrané součásti.
V existující databázi zásob (s názvem InventoryDB) jsou uloženy informace o součástech v jediné tabulce s názvem BoilerParts. Kiana určuje, že webové rozhraní API by mělo podporovat následující požadavky:
- Získat všechny součásti kotle.
- Získat podrobnosti o součásti vzhledem k ID součásti.
Definování operací webového API: Znalostní databáze pro práci v terénu
Ve stávajícím systému databáze znalostí (pojmenovaná KnowledgeDB) obsahuje tři tabulky, které zaznamenávají a spravují vztahy mezi tipy, techniky a součástmi:
- Tipy obsahují podrobnosti o tipu. Každý tip obsahuje souhrn jednoho řádku identifikující konkrétní problém (předmět) a podrobnější vysvětlení popisující, jak problém vyřešit (text). Každý tip také odkazuje na část a technika, který tip zaznamenal.
- BoilerParts obsahuje seznam částí, na které odkazují tipy. Podrobnosti o samotných součástech jsou uloženy v tabulce BoilerParts v databázi InventoryDB.
- Technici uvádí seznam techniků, kteří každý tip napsali.
Část aplikace znalostní báze aktuálně obsahuje obrazovku Prohlížeč zástupného symbolu. Maria chce implementovat následující funkce:
Technik určí hledaný termín na obrazovce Procházet, aby našel všechny odpovídající tipy. Shoda může být v názvu části, na kterou tip odkazuje, textu v předmětu nebo textu tipu nebo v názvu technika, který je odborníkem s konkrétním vybavením.
Po nalezení všech odpovídajících tipů může technik vybrat tip a zobrazit jeho podrobnosti.
Technik může také přidat nové tipy do znalostní báze a také přidat poznámky a komentáře ke stávajícím tipům.
Znalostní báze je velká a roste a dotazování napříč několika tabulkami a sloupci může zahrnovat složitou logiku, která vyžaduje značný výpočetní výkon. Pro snížení zatížení webového API se Kiana rozhodla použít službu Azure Cognitive Search k poskytování funkce vyhledávání, jak bylo popsáno výše. Pro podporu aplikace se Kiana rozhodne, že z webového rozhraní API jsou vyžadovány následující operace:
Podrobnosti o konkrétním tipu znalostní báze najít v tabulce Tipy.
Aktualizovat existující tip znalostní báze v tabulce Tipy.
Přidejte nový tip znalostní báze do tabulky Tipy, což může také zahrnovat přidání řádků do tabulek BoilerParts a Technici, pokud zadaná součást nebo technik aktuálně nemá k nim zaznamenány žádné tipy. Rutina, která ve skutečnosti provádí logiku za přidáním nového tipu, bude implementována jako logická aplikace volaná z Power Apps.
Definování operací webového API: plánováno práce v terénu
Plánování schůzek techniků vyžaduje nejen dotazování, přidávání a odebírání schůzek, ale také zaznamenávání informací o zákaznících. Stávající systém schůzek zaznamenává tato data do tří tabulek v databázi SchedulesDB:
- Schůzky obsahují podrobnosti o každé schůzce, včetně data, času, problému, poznámek a technika přiřazeného k úkolu.
- Zákazníci obsahují podrobnosti o každém zákazníkovi, včetně jeho jména, adresy a kontaktních údajů.
- Technici uvádí seznam všech techniků účastnících se schůzek.
Poznámka
Databáze ve skutečnosti obsahuje čtvrtou pojmenovanou tabulku AppointmentsStatus. Tato tabulka obsahuje seznam platných hodnot pro stav schůzky a je to pouze vyhledávání používané jinými částmi stávajícího systému schůzek.
Kiana se rozhodne, že následující operace by byly užitečné pro část aplikace Field Scheduling:
- Najděte všechny schůzky pro konkrétního technika.
- Najděte všechny schůzky pro konkrétního technika na aktuální den.
- Najděte další plánovanou schůzku pro konkrétního technika.
- Aktualizujte podrobnosti schůzky, například přidejte poznámky nebo fotografii.
- Najděte podrobnosti o zákazníkovi.
Tvorba webového API: Správa inventáře v terénu
Existující systémy ukládají data pomocí Azure SQL Database. Kiana se rozhodne vytvořit webové rozhraní API pomocí Entity Framework Core, protože tento přístup může generovat spoustu kódu, který automaticky dotazuje, vkládá a aktualizuje data. Šablona webového rozhraní API poskytovaná společností Microsoft může také vytvářet popisy Swagger, které popisují každou operaci v rozhraní API. Tyto popisy jsou užitečné pro testování operací API. Mnoho nástrojů může tyto informace použít k integraci API s dalšími službami, jako je Azure API Management.
Kiana začala s funkčností Field Inventory, protože toto je ta nejjednodušší část. Operace Field Inventory ve webovém rozhraní API dotazují jednu tabulku, BoilerParts v databázi InventoryDB. Tato tabulka obsahuje sloupce zobrazené na následujícím obrázku.

Kiana zvolila při vytváření webového rozhraní API přístup „kód na prvním místě“. S touto strategií udělala následující:
Definovala vlastní třídu C#model, která zrcadlila strukturu tabulky BoilerParts v databázi InventoryDB.
Vytvořila třídu Entity Framework kontext, kterou webové rozhraní API používá k připojení k databázi, k provádění dotazů.
Nakonfigurovala kontextovou třídu pro připojení k databázi InventoryDB v Azure.
Použila nástroje příkazového řádku Entity Framework pro vygenerování třídy rozhraní Web API kontroler, která implementuje požadavky HTTP REST pro každou z operací, které lze provést proti tabulce BoilerParts.
K testování webového rozhraní API použila rozhraní Swagger API.
Následující obrázek ukazuje strukturu webového rozhraní API na vysoké úrovni.

Kiana pomocí následujícího postupu vytvořila webové rozhraní API pomocí nástrojů příkazového řádku .NET 5.0 a Visual Studio Code:
Otevřete okno terminálu v Visual Studio Code.

Spuštěním následujícího příkazu vytvořte nový projekt webového rozhraní API s názvem FieldEngineerApi.
dotnet new webapi -o FieldEngineerApiOtevřete složku FieldEngineerApi.

Odstraňte ukázkový kontroler WeatherForecastController.cs a soubor třídy WeatherForecast.cs, který byl vytvořen pomocí šablony webového rozhraní API.

V okně Terminál přidejte do projektu následující balíčky a nástroje Entity Framework spolu s podporou používání serveru SQL.
dotnet add package Microsoft.EntityFrameworkCore.SqlServer dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design dotnet add package Microsoft.EntityFrameworkCore.Design dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson dotnet tool install --global dotnet-ef dotnet tool install --global dotnet-aspnet-codegeneratorVe složce FieldEngineerApi vytvořte novou složku s názvem Modely.

Ve složce Modely vytvořte soubor kódu C.# pojmenovaný BoilerPart.cs.

V tomto souboru přidejte následující vlastnosti a pole. Tyto vlastnosti a pole odrážejí strukturu tabulky BoilerParts v databázi InventoryDB.
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace FieldEngineerApi.Models { public class BoilerPart { [Key] public long Id { get; set; } public string Name { get; set; } public string CategoryId { get; set; } [Column(TypeName = "money")] public decimal Price { get; set; } public string Overview { get; set; } public int NumberInStock { get; set; } public string ImageUrl { get; set; } } }Ve složce Modely vytvořte další soubor kódu C.# pojmenovaný InventoryContext.cs. Přidejte do této třídy následující kód. Třída poskytuje spojení mezi kontrolerem (bude vytvořen dále) a databází.
using Microsoft.EntityFrameworkCore; namespace FieldEngineerApi.Models { public class InventoryContext : DbContext { public InventoryContext(DbContextOptions<InventoryContext> options) : base(options) { } public DbSet\<BoilerPart\> BoilerParts { get; set; } } }Upravte soubor appsettings.Development.json pro projekt a přidejte sekci ConnectionStrings s následujícím připojovacím řetězcem InventoryDB. Nahraďte <server name> jménem serveru SQL Database, který jste vytvořili pro uložení databáze InventoryDB.
{ "ConnectionStrings": { "InventoryDB": "Server=tcp*:<server name>*.database.windows.net,1433;Initial Catalog=InventoryDB;Persist Security Info=False;User ID=sqladmin;Password=Pa55w.rd;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } } }Důležité
Pouze pro účely této příručky obsahuje připojovací řetězec ID uživatele a heslo pro databázi. V produkčním systému byste nikdy neměli tyto položky ukládat jako text v konfiguračním souboru.
Upravte soubor Startup.cs a přidejte následující direktivy používání do seznamu na začátku souboru.
using FieldEngineerApi.Models; using Microsoft.EntityFrameworkCore;V třídě Startup třídy, najděte metodu ConfigureServices. Přidejte do této metody následující výraz.
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<InventoryContext>(options => options.UseSqlServer(Configuration.GetConnectionString("InventoryDB"))); services.AddControllers(); ... }Upravte metodu Konfigurovat a povolte uživatelské rozhraní Swagger, i když je aplikace spuštěna v produkčním režimu, jak je znázorněno (tato změna zahrnuje přemístění dvou volání metody app.UseSwagger mimo výraz IF).
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "FieldEngineerApi v1")); ... }Důležité
Tato změna umožňuje zpřístupnění Swagger koncového bodu pro integraci API Management. Po nakonfigurování API Management byste měli tento kód přesunout zpět dovnitř výrazu IF a znovu nasadit webové rozhraní API. Nikdy nenechávejte Swagger koncový bod otevřený v produkčním systému.
V okně Terminál spusťte následující příkaz pro vygenerování kontroleru BoilerParts z třídey modelu BoilerPart a kontextové třídy InventoryContext.
dotnet aspnet-codegenerator controller ^ -name BoilerPartsController -async -api ^ -m BoilerPart -dc InventoryContext -outDir ControllersKontroler BoilerParts by měl být vytvořen ve složce Kontroléry.
[!NOTE] Znak zakončení řádku ^ je rozpoznán pouze systémem Windows. Pokud spouštíte Visual Studio Code v systému Linux, použijte znak \.
Otevřete soubor BoilerParts.cs ve složce Kontroléry a zkontrolujte její obsah. Třída BoilerPartsController zpřístupňuje následující metody REST:
- GetBoilerParts(), která vrací seznam všech objektů BoilerParts z databáze.
- GetBoilerPart(long id), která načte podrobnosti o zadané části kotle.
- PutBoilerPart(long id, BoilerPart boilerPart), která aktualizuje část kotle v databázi s podrobnostmi v objektu BoilerPart zadaném jako parametr.
- PostBoilerPart(BoilerPart boilerPart), která vytváří novou část kotle.
- DeleteBoilerPart(long id), která odstraní zadanou část kotle z databáze.
Poznámka
Aplikace technika vyžaduje pouze tyto dvě metody Get, ale ostatní jsou užitečné pro aplikaci pro správu inventáře na ploše (tato příručka se jí nezabývá).
Zkompilujte a vytvořte webové rozhraní API.
dotnet build
Webové rozhraní API by se mělo vytvářet bez hlášení chyb nebo varování.
Nasazení webového rozhraní API do Azure: Správa zásob v terénu
Kiana nasadila a otestovala webové rozhraní API provedením následujících úkolů:
Pomocí rozšíření účtu Azure ve Visual Studio Code se přihlaste k předplatnému Azure.
Z okna Terminál ve Visual Studio Code vytvořte novou skupinu zdrojů s názvem webapi_rg ve svém předplatném Azure. V následujícím příkazu nahraďte <location> nejbližší oblastí Azure.
az group create ^ --name webapi_rg ^ --location <location>Vytvořte plán Azure App Service a poskytněte prostředky pro hostování webového rozhraní API.
az appservice plan create ^ --name webapi_plan ^ --resource-group webapi_rg ^ --sku F1Poznámka
F1 je SKU zdarma pro plány App Service. Poskytuje omezenou propustnost a kapacitu a je vhodné pouze pro vývojové účely.
Vytvořte webovou aplikaci Azure pomocí plánu App Service. Nahraďte <webapp name> jedinečným názvem pro webovou aplikaci.
az webapp create ^ --name <webapp name> ^ --resource-group webapi_rg ^ --plan webapi_planVe Visual Studio Code upravte soubor appSettings.json a přidejte stejný připojovací řetězec, který jste dříve napsali do souboru appSettings.Development.json. Nezapomeňte nahradit <server name> jménem serveru SQL Database, který jste vytvořili pro uložení databáze InventoryDB.
{ "ConnectionStrings": { "InventoryDB": "Server=tcp:<server name>.database.windows.net,1433;Initial Catalog=InventoryDB;Persist Security Info=False;User ID=sqladmin;Password=Pa55w.rd;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"** }, "Logging": { "LogLevel": { "Default\: "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*" }V okně Terminál zabalte webové rozhraní API připravené k nasazení do Azure.
dotnet publish -c Release -o ./publishTento příkaz uloží zabalené soubory do složky s názvem publikovat.
Ve Visual Studio Code klepněte pravým tlačítkem na složku publikovat a poté vyberte Nasazení do webové aplikace.

Vyberte název webové aplikace, kterou jste vytvořili dříve v kroku 4 (<webapp name>). V následujícím příkladu je webová aplikace pojmenována my-fieldengineer-webapp.

Na výzvu v dialogovém okně Visual Studio Code vyberte Nasadit, chcete-li přijmout varování a nasadit webovou aplikaci.

Ověřte, zda je webová aplikace úspěšně nasazena, a poté přejděte na web.

Web se otevře v novém okně prohlížeče, ale zobrazí chybu HTTP 404 (nenalezena). Důvodem je, že operace webového API jsou k dispozici prostřednictvím koncového bodu api místo kořenového adresáře webu. Změňte adresu URL na https://<webapp name>.azurewebsites.net/api/BoilerParts. Tento identifikátor URI vyvolá metodu GetBoilerParts v kontroleru BoilerParts. Webové rozhraní API by mělo reagovat s dokumentem JSON, který uvádí všechny součásti kotle v databázi InventoryDB.

Změňte adresu URL v prohlížeči na https://<webapp name>.azurewebsites.net/swagger. Mělo by se objevit Swagger API. Toto je grafické uživatelské rozhraní, které vývojáři umožňuje ověřit a otestovat každou z operací ve webovém rozhraní API. Funguje také jako užitečný dokumentační nástroj.

Vyberte GET sousedící s koncovým bodem /api/BoilerParts/{id} a poté vyberte Vyzkoušet.

Do pole id zadejte ID součásti a poté vyberte Provést. Tato akce vyvolá metodu GetBoilerPart(long id) v kontroleru BoilerParts. Vrátí dokument JSON s podrobnostmi o součásti nebo chybu HTTP 404, pokud v databázi není nalezena žádná odpovídající část.

Zavřete webový prohlížeč a vraťte se do Visual Studio Code.
Vytváření a nasazování webového rozhraní API: Znalostní báze týkající se práce v terénu
Operace Znalostní báze týkající se práce v terénu ve webovém rozhraní API fungují na třech tabulkách v databázi KnowledgeDB: Tipy, Kotlové díly a Technici. Následující obrázek ukazuje vztahy mezi těmito tabulkami a sloupci, které obsahují.

Kiana přijala podobný přístup k databázi FZnalostní báze týkající se práce v terénu, který použila pro databázi Field Inventory Management. Plnila následující úkoly:
Vytvořit třídy modelu C.#, které odrážejí strukturu tabulky Tipy, Kotlové díly a Technici v databázi KnowledgeDB. Kód pro každou z těchto tříd je uveden v následujícím textu.
Poznámka
Tabulka Kotlové díly v databázi KnowledgeDB se liší od tabulky Kotlové díly v databázi InventoryDB. Aby se předešlo střetu jmen, třídy modelu pro tabulky v databázi KnowledgeDB mají předponu KnowledgeBase.
// KnowledgeBaseTips.cs using System.ComponentModel.DataAnnotations; namespace FieldEngineerApi.Models { public class KnowledgeBaseTip { [Key] public long Id { get; set; } public long KnowledgeBaseBoilerPartId { get; set; } public virtual KnowledgeBaseBoilerPart KnowledgeBaseBoilerPart { get; set; } public string KnowledgeBaseEngineerId { get; set; } public virtual KnowledgeBaseEngineer KnowledgeBaseEngineer { get; set; } public string Subject { get; set; } public string Body { get; set; } } }Poznámka
ID technika je řetězec, ne číslo. Důvodem je, že stávající systémy používají identifikátory GUID k identifikaci techniků a dalších uživatelů.
// KnowledgeBaseBoilerPart.cs using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace FieldEngineerApi.Models { public class KnowledgeBaseBoilerPart { [Key] public long Id { get; set; } public string Name { get; set; } public string Overview { get; set; } public virtual ICollection<KnowledgeBaseTip> KnowledgeBaseTips { get; set; } } }// KnowledgeBaseEngineer.cs using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace FieldEngineerApi.Models { public class KnowledgeBaseEngineer { [Key] public string Id { get; set; } [Required] public string Name { get; set; } public string ContactNumber { get; set; } public virtual ICollection<KnowledgeBaseTip> KnowledgeBaseTips { get; set; } } }Vytvořit další třídu Entity Framework kontext, kterou webové rozhraní API používá k připojení k databázi KnowledgeDB.
// KnowledgeBaseContext.cs using Microsoft.EntityFrameworkCore; namespace FieldEngineerApi.Models { public class KnowledgeBaseContext : DbContext { public KnowledgeBaseContext(DbContextOptions<KnowledgeBaseContext> options) : base(options) { } public DbSet<KnowledgeBaseBoilerPart> BoilerParts { get; set; } public DbSet<KnowledgeBaseEngineer> Engineers { get; set; } public DbSet<KnowledgeBaseTip> Tips { get; set; } } }Upravte soubor appsettings.Development.json pro projekt a přidejte následující připojovací řetězec KnowledgDB do sekce ConnectionStrings. Nahraďte <server name> jménem serveru SQL Database, který jste vytvořili pro uložení databáze KnowledgeDB.
{ "ConnectionStrings": { "InventoryDB": "Server=tcp:...", "KnowledgeDB": "Server=tcp:<server name>.database.windows.net,1433;Initial Catalog=KnowledgeDB;Persist Security Info=False;User ID=sqladmin;Password=Pa55w.rd;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" }, "Logging": { ... } } }Důležité
Pouze pro účely této příručky obsahuje připojovací řetězec ID uživatele a heslo pro databázi. V produkčním systému byste nikdy neměli tyto položky ukládat jako text v konfiguračním souboru.
Upravte soubor Startup.cs a v metodě ConfigureServices přidejte následující výrazy.
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<InventoryContext>...; services.AddDbContext<KnowledgeBaseContext>(options => options.UseSqlServer(Configuration.GetConnectionString("KnowledgeD"))); services.AddControllers().AddNewtonsoftJson( options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore** ); services.AddControllers(); ... }Druhý výraz řídí způsob, jakým jsou data serializována, když jsou načtena. Některé z modelových tříd mají odkazy na jiné modelové třídy, což může odkazovat na další modelové třídy. Některé z těchto odkazů mohou vyústit v rekurzivní smyčky (Entita A odkazuje na Entitu B, která odkazuje zpět na Entitu A, která odkazuje na Entitu B znovu atd.). Možnost ReferenceLoopHandling způsobí, že serializátor ignoruje takové smyčky v datech a vrátí pouze entitu a objekty, na které okamžitě odkazuje, ale nic víc.
V okně Terminál spusťte následující příkaz a vygenerujte kontrolery z tříd modelů KnowledgeBaseBoilerTip, KnowledgeBaseBoilerPart a KnowledgeBaseEngineer a kontextové třídy KnowledgeBaseContext.
dotnet aspnet-codegenerator controller ^ -name KnowledgeBaseTipController -async -api ^ -m KnowledgeBaseTip ^ -dc KnowledgeBaseContext -outDir Controllers dotnet aspnet-codegenerator controller ^ -name KnowledgeBaseBoilerPartController -async -api ^ -m KnowledgeBaseBoilerPart ^ -dc KnowledgeBaseContext -outDir Controllers dotnet aspnet-codegenerator controller ^ -name KnowledgeBaseEngineerController -async -api ^ -m KnowledgeBaseEngineer ^ -dc KnowledgeBaseContext -outDir ControllersVšechny kontroléry by měly být vytvořeny ve složce Kontroléry.
Upravte soubor KnowledgeBaseBoilerPartController.cs. Tento soubor obsahuje kód pro kontroler KnowledgeBaseBoilerPart. Mělo by se řídit stejným vzorem jako třída BoilerPartsController vytvořená dříve, vystavující metody REST, které klientovi umožňují vypsat, dotazovat, vložit, aktualizovat a odstranit entity. Přidejte následující metodu GetTipsForPart do kontroleru.
[Route("api/[controller]")] [ApiController] public class KnowledgeBaseBoilerPartController : ControllerBase { private readonly KnowledgeBaseContext _context; public KnowledgeBaseBoilerPartController(KnowledgeBaseContext context) { _context = context; } // GET: api/KnowledgeBaseBoilerPart/5/Tips [HttpGet("{id}/Tips")] public async Task<ActionResult<IEnumerable<KnowledgeBaseTip>>>GetTipsForPart(long id) { return await _context.Tips.Where( t => t.KnowledgeBaseBoilerPartId == id).ToListAsync(); } ... }Tato metoda vrací všechny tipy znalostní báze, které odkazují na zadanou část. Dotazuje tybulku Tipy v databázi prostřednictvím objektu KnowledgeBaseContext k vyhledání těchto informací.
Upravte soubor KnowledgeBaseEngineerController.cs a přidejte následující metodu do třídy KnowledgeBaseEngineerController.
[Route("api/[controller]")] [ApiController] public class KnowledgeBaseEngineerController : ControllerBase { private readonly KnowledgeBaseContext _context; public KnowledgeBaseEngineerController(KnowledgeBaseContext context) { _context = context; } // GET: api/KnowledgeBaseEngineer/5/Tips [HttpGet("{id}/Tips")] public async Task\<ActionResult<IEnumerable<KnowledgeBaseTip>>> GetTipsForEngineer(string id) { return await _context.Tips.Where(t => t.KnowledgeBaseEngineerId == id).ToListAsync(); } ... }Metoda GetTipsForEngineer najde všechny tipy znalostní báze zveřejněné zadaným technikem.
V okně Terminál zkompilujte a sestavte webové rozhraní API.
dotnet buildWebové rozhraní API by se mělo vytvářet bez hlášení chyb nebo varování.
Upravte soubor appSettings.json a přidejte připojovací řetězec pro databázi KnowledgeDB. Tento řetězec by měl být stejný, jaký jste dříve napsali do souboru appSettings.Development.json.
{ "ConnectionStrings": { "InventoryDB": ..., "KnowledgeDB": "Server=tcp:<server name>.database.windows.net,1433;Initial Catalog=KnowledgeDB;Persist Security Info=False;User ID=sqladmin;Password=Pa55w.rd;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" }, "Logging": { ... }, "AllowedHosts": "*" }V okně Terminál zabalte webové rozhraní API připravené k nasazení do Azure.
dotnet publish -c Release -o ./publishVe Visual Studio Code klepněte pravým tlačítkem na složku publikovat a poté vyberte Nasazení do webové aplikace. Proveďte nasazení do stejné webové aplikace Azure, kterou jste vytvořili dříve. Povolte průvodci přepsat stávající webovou aplikaci novým kódem.
Po dokončení nasazení přejděte na web, ale změňte adresu URL v prohlížeči na https://<webapp name>.azurewebsites.net/swagger. Operace pro kontrolery KnowledgeBaseBoilerPart, KnowledgeBaseEngineer a KnowldgeBaseTip by měly být uvedeny vedle stávajících operací BoilerParts. Ověřte, že operace KnowledgeBaseBoilerPart zahrnují operaci GET pro identifikátor URI /api/KnowledgeBaseBoilerPart/{id}/Tips a operaci KnowledgeBaseEngineer zahrnují operaci GET pro identifikátor URI /api/KnowledgeBaseEngineer/{id}/Tips.

Vytváření a nasazování webového rozhraní API: Plánování práce v terénu
Operace Plánování práce v terénu používají tabulky Schůzky, AppointmentStatuses (toto je jednoduchá vyhledávací tabulka se seznamem platných hodnot stavu schůzky), Zákazníci a Technici zobrazené na následujícím obrázku. Tyto tabulky jsou uloženy v databázi SchedulesDB.

Kiana vytvořila operace webového API pro část systému Plánování práce v terénu v systému a provedla následující úkoly:
Vytvořit třídy modelu C#., které odrážejí strukturu tabulky AppointmentStatus, Schůzky, Zákazníci a Technici v databázi SchedulesDB. Následující kód zobrazuje každou z těchto tříd.
Poznámka
Třída modelu pro tabulku Technici je pojmenována ScheduleEngineer pro odlišení od modelu pro tabulku Technici v databázi InventoryDB.
// AppointmentStatus.cs using Newtonsoft.Json; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace FieldEngineerApi.Models { public class AppointmentStatus { [Key] public long Id { get; set; } public string StatusName { get; set; } [JsonIgnore] public virtual ICollection<Appointment> Appointments { get; set; } } }// Appointment.cs using System; using System.ComponentModel.DataAnnotations; namespace FieldEngineerApi.Models { public class Appointment { [Key] public long Id { get; set; } [Required] public long CustomerId { get; set; } public virtual Customer Customer { get; set; } public string ProblemDetails { get; set; } [Required] public long AppointmentStatusId { get; set; } public virtual AppointmentStatus AppointmentStatus { get; set; } public string EngineerId { get; set; } public virtual ScheduleEngineer Engineer { get ; set; } [Display(Name = "StartTime")] [DataType(DataType.DateTime)] [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy H:mm:ss}")] public DateTime StartDateTime { get; set; } public string Notes { get; set; } public string ImageUrl { get; set; } } }// Customer.cs using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace FieldEngineerApi.Models { public class Customer { [Key] public long Id { get; set; } [Required] public string Name { get; set; } public string Address { get; set; } public string ContactNumber { get; set; } public virtual ICollection<Appointment> Appointments { get; set; } } }// ScheduleEngineer.cs using Newtonsoft.Json; using System.ComponentModel.DataAnnotations; using System.Collections.Generic; namespace FieldEngineerApi.Models { public class ScheduleEngineer { [Key] public string Id { get; set; } [Required] public string Name { get; set; } public string ContactNumber { get; set; } [JsonIgnore] public virtual ICollection<Appointment> Appointments { get; set; } } }Vytvořit třídu Entity Framework kontext, kterou webové rozhraní API používá k připojení k databázi SchedulesDB.
// ScheduleContext.cs using System; using Microsoft.EntityFrameworkCore; namespace FieldEngineerApi.Models { public class ScheduleContext : DbContext { public ScheduleContext(DbContextOptions<ScheduleContext> options) : base(options) { } public DbSet<Appointment> Appointments { get; set; } public DbSet<AppointmentStatus> AppointmentStatuses { get; set; } public DbSet<Customer> Customers { get; set; } public DbSet<ScheduleEngineer> Engineers { get; set; } } }Upravte soubor appsettings.Development.json pro projekt a přidejte následující připojovací řetězec SchedulesDB do sekce ConnectionStrings. Nahraďte <server name> jménem serveru SQL Database, který jste vytvořili pro uložení databáze KnowledgeDB.
{ "ConnectionStrings": { "InventoryDB": "Server=tcp*: ...", "KnowledgeDB": "Server=tcp; ... ", "SchedulesDB": "Server=tcp:<server name>.database.windows.net,1433;Initial Catalog=SchedulesDB;Persist Security Info=False;User ID=sqladmin;Password=Pa55w.rd;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" }, "Logging": { ... } } }Upravte soubor Startup.cs a v metodě ConfigureServices přidejte následující výraz.
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<InventoryContext>...; services.AddDbContex\<KnowledgeBaseContext>...; services.AddDbContext<ScheduleContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SchedulesDB"))); services.AddControllers().AddNewtonsoftJson(...); ... }V okně Terminál spusťte následující příkaz a vygenerujte kontrolery z tříd modelů Schůzka, Zákazníci a ScheduleEngineer a kontextové třídy ScheduleContext.
Poznámka
Nevytvářejte samostatný kontroler pro model AppointmentStatus.
dotnet aspnet-codegenerator controller ^ -name AppointmentsController -async -api ^ -m Appointment ^ -dc ScheduleContext -outDir Controllers dotnet aspnet-codegenerator controller ^ -name CustomerController -async -api ^ -m Customer ^ -dc ScheduleContext -outDir Controllers dotnet aspnet-codegenerator controller ^ -name ScheduleEngineerController -async -api ^ -m ScheduleEngineer ^ -dc ScheduleContext -outDir ControllersUpravte soubor AppointmentsController.cs. Ve třídě AppointmentsController najděte metodu GetAppointments. Upravte výraz return, jak je znázorněno. Tato změna zajišťuje, že jsou informace Zákazník, Technik a AppointmentStatus načítány jako součást operace GET; tato pole odkazují na další entity, které by jinak byly ponechány null kvůli opožděnému mechanismu načítání Entity Framework.
public class AppointmentsController : ControllerBase { private readonly ScheduleContext _context; public AppointmentsController(ScheduleContext context) { _context = context; } // GET: api/Appointments [HttpGet] public async Task<ActionResult<IEnumerable<Appointment>>> GetAppointments() { return await _context.Appointments .Include(c => c.Customer) .Include(e => e.Engineer) .Include(s => s.AppointmentStatus) .ToListAsync(); } ... }Ve stejném souboru upravte metodu GetAppointment(long id) tak, jak je znázorněno.
// GET: api/Appointments/5 [HttpGet("{id}")] public async Task<ActionResult<Appointment>> GetAppointment(long id) { var appointment = _context.Appointments .Where(a => a.Id == id) .Include(c => c.Customer) .Include(e => e.Engineer) .Include(s => s.AppointmentStatus); var appData = await appointment.FirstOrDefaultAsync(); if (appData == null) { return NotFound(); } return appData; }Tato verze metody vyplní pole Zákazník, Technik a AppointmentStatus schůzky, když je načtena (opožděné načítání by jinak ponechalo tato pole prázdná).
Najděte metodu PutAppointment a nahraďte ji následujícím kódem. Tato verze metody PutAppointment převezme pole v události, kterou může uživatel upravit v aplikaci, nikoli úplný oběkt Schůzka.
[HttpPut("{id}")] public async Task<IActionResult> PutAppointment(long id, string problemDetails, string statusName, string notes, string imageUrl) { var statusId = _context.AppointmentStatuses.First(s => s.StatusName == statusName).Id; var appointment = _context.Appointments.First(e => e.Id == id); if (appointment == null) { return BadRequest(); } appointment.ProblemDetails = problemDetails; appointment.AppointmentStatusId = statusId; appointment.Notes = notes; appointment.ImageUrl = imageUrl; _context.Entry(appointment).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!AppointmentExists(id)) { return NotFound(); } else { throw; } } return NoContent(); }Poznámka
Obecně platí, že operace PUT by měly upravovat pouze data, která by měl mít uživatel možnost aktualizovat, ne nutně každé pole v entitě.
Otevřete soubor ScheduleEngineerController.cs a přidejte následující metodu GetScheduleEngineerAppointments do třídy ScheduleEngineerController.
[Route("api/[controller]")] [ApiController] public class ScheduleEngineerController : ControllerBase { private readonly ScheduleContext _context; public ScheduleEngineerController(ScheduleContext context) { _context = context; } // GET: api/ScheduleEngineer/5/Appointments [HttpGet("{id}/Appointments")] public async Task<ActionResult<IEnumerable<Appointment>>> GetScheduleEngineerAppointments(string id) { return await _context.Appointments .Where(a => a.EngineerId == id) .OrderByDescending(a => a.StartDateTime) .Include(c => c.Customer) .Include(e => e.Engineer) .Include(s => s.AppointmentStatus) .ToListAsync(); } ... } These methods retrieve the appointments for the specified technician.Edit the CustomerController.cs file and add the GetAppointments and GetNotes methods, as shown, to the CustomerController class.
[Route("api/[controller]")] [ApiController] public class CustomerController : ControllerBase { private readonly ScheduleContext _context; public CustomerController(ScheduleContext context) { _context = context; } //GET: api/Customers/5/Appointments [HttpGet("{id}/Appointments")] public async Task<ActionResult<IEnumerable<Appointment>>> GetAppointments(long id) { return await _context.Appointments .Where(a => a.CustomerId == id) .OrderByDescending(a => a.StartDateTime) .ToListAsync(); } //GET: api/Customers/5/Notes [HttpGet("{id}/Notes")] public async Task<ActionResult<IEnumerable<object>>> GetNotes(long id) { return await _context.Appointments .Where(a => a.CustomerId == id) .OrderByDescending(a => a.StartDateTime) .Select(a => new {a.StartDateTime, a.ProblemDetails, a.Notes}) .ToListAsync(); } ... }Metoda GetAppointments vyhledá všechny schůzky pro zadaného zákazníka. Metoda GetNotes načte všechny poznámky, které technik udělal při předchozích návštěvách zákazníka.
Upravte soubor appSettings.json a přidejte připojovací řetězec pro databázi KnowledgeDB. Tento řetězec by měl být stejný, jaký jste dříve napsali do souboru appSettings.Development.json.
{ "ConnectionStrings": { "InventoryDB": ..., "KnowledgeDB": ..., "SchedulesDB": "Server=tcp:<server name>.database.windows.net,1433;Initial Catalog=SchedulesDB;Persist Security Info=False;User ID=sqladmin;Password=Pa55w.rd;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" }, "Logging": { ... }, "AllowedHosts": "*" }V okně Terminál zkompilujte a sestavte webové rozhraní API.
dotnet buildWebové rozhraní API by se mělo vytvářet bez hlášení chyb nebo varování.
V okně Terminál zabalte webové rozhraní API připravené k nasazení do Azure.
dotnet publish -c Release -o ./publishVe Visual Studio Code klepněte pravým tlačítkem na složku publikovat a poté vyberte Nasazení do webové aplikace. Proveďte nasazení do stejné webové aplikace Azure, kterou jste vytvořili dříve. Povolte průvodci přepsat stávající webovou aplikaci novým kódem.
Po dokončení nasazení přejděte na web, ale změňte adresu URL v prohlížeči na https://<webapp name>.azurewebsites.net/swagger. Ověřte, že operace pro kontrolery Schůzky, Zákazník a ScheduleEngineer jsou nyní k dispozici.
Webové rozhraní API je nyní připraveno k začlenění do aplikace.
Váš názor
Odeslat a zobrazit názory pro