ASP.NET Core MVC je implementace designového vzoru Model-View-Controller (MVC), který je oblíbený pro vývoj komplexních webových stránek. V tomto modelu se oddělují logika aplikace, uživatelské rozhraní a ovládání toku dat, což umožňuje snadnou údržbu a rozšiřování aplikace. Vývoj webového uživatelského rozhraní pomocí ASP.NET Core MVC se podrobně probírá v kapitole 15, kde se ukazuje, jak vytvořit interaktivní a efektivní webové aplikace.

Pro zjednodušení a zpřehlednění tvorby opakovaně použitelných uživatelských komponent je možné využít Razor Class Libraries, které slouží jako balíčky funkčnosti pro ASP.NET Core projekty. Tato technologie umožňuje snadnou tvorbu komponent, které mohou být následně využívány v různých aplikacích.

Blazor je další zajímavou technologií v rámci ASP.NET Core, která umožňuje vývoj uživatelských rozhraní pomocí C# a .NET, což přináší oproti tradičním JavaScriptovým rámcům jako Angular, React či Vue značnou výhodu v konzistenci jazyka napříč celou aplikací. Blazor WebAssembly běží přímo v prohlížeči podobně jako JavaScript, zatímco Blazor Server vykonává kód na serveru a dynamicky aktualizuje webovou stránku. Blazor není určen pouze pro tvorbu webových aplikací, ale může být využit také pro vytváření hybridních mobilních a desktopových aplikací, pokud je kombinován s .NET MAUI. Tato kombinace přináší silnou platformu pro multiplatformní vývoj, kterou se budeme podrobněji zabývat v kapitolách 16 a 17.

Pokud jde o vývoj služeb, technologie jako Web API a Minimal APIs jsou skvélé pro výstavbu webových služeb, které používají HTTP jako základní komunikační technologii a dodržují designová pravidla REST architektury dle Roye Fieldinga. Služby mohou být kategorizovány podle jejich složitosti: od monolitických služeb, které poskytují veškerou funkčnost pro klientské aplikace, až po mikroservices, které se zaměřují na konkrétní, menší funkce, a nanoservices, které poskytují jedinou funkci a aktivují se jen na požádání, čímž šetří prostředky.

Různé technologie poskytují různé možnosti v závislosti na potřebách aplikace. Například gRPC je skvélé pro vytváření vysoce efektivních mikroservices s nízkou latencí, zatímco SignalR je ideální pro real-time komunikaci mezi komponentami, která je často potřeba v moderních aplikacích. OData a GraphQL zase usnadňují práci s komplexními datovými modely a poskytují flexibilitu v získávání dat z různých zdrojů. Azure Functions pak představují serverless nanoservices, které nemusí běžet nepřetržitě, což je činí ideálními pro situace, kde jsou náklady na provoz důležité.

WCF (Windows Communication Foundation), který byl původně součástí .NET Frameworku 3.0, je technologie určená pro budování distribuovaných aplikací. WCF umožňuje volání vzdálených procedur (RPC) mezi klientskými a serverovými aplikacemi a poskytuje flexibilitu při výběru komunikační technologie. Nicméně, Microsoft se rozhodl neprovést oficiální port WCF na moderní .NET, a tak vznikl komunitní projekt Core WCF, který je spravován nadací .NET Foundation. Pokud potřebujete migrovat existující službu z .NET Frameworku do moderního .NET, Core WCF vám může pomoci, ale je třeba si být vědom omezení, protože některé části WCF jsou specifické pro Windows.

Pokud jde o doporučení pro různé scénáře, je důležité si uvědomit, že každá technologie má své výhody a nevýhody v závislosti na tom, co konkrétní aplikace potřebuje. Pro veřejné služby, které musí být přístupné z prohlížeče nebo mobilních zařízení, jsou ideální služby založené na HTTP/1.1. OData a GraphQL jsou pak výbornou volbou pro komplexní datové služby, které zahrnují hierarchická data. Pokud je kladen důraz na nízkou latenci a vysoký výkon, gRPC je jasnou volbou pro mikroservices a interní komunikaci.

Pro scénáře, kde je potřeba komunikace v reálném čase, je SignalR výbornou volbou, přičemž pro složitější real-time aplikace s velkým počtem klientů je vhodné SignalR použít na straně serveru, který následně rozesílá zprávy klientům. Naopak pro prostředí, kde je kladeno důraz na efektivní přenos dat a menší šířku pásma, je gRPC ideální volbou díky používání Protobuf formátu, který je mnohem kompaktnější než JSON.

Technologie jako Azure Functions jsou výborné pro nanoservices, které nevyžadují trvalý běh, a jsou skvélé pro případy, kdy služba potřebuje reagovat na události, ale nemusí běžet neustále. Tato flexibilita dává vývojářům větší kontrolu nad náklady na provoz.

V neposlední řadě, pro vývoj desktopových aplikací zaměřených na Windows, Microsoft poskytuje různé platformy, které se postupně vyvinuly od Windows Forms přes WPF až po nejnovější Windows App SDK, které nabízí moderní přístup k vývoji aplikací pro Windows 10 a 11. Tyto technologie stále využívají bohatý ekosystém Windows, ale zároveň čelí výzvám moderního vývoje, kde se očekává podpora multiplatformních řešení a integrace s cloudovými službami.

Jak efektivně používat Bootstrap pro webové rozhraní: Praktické techniky a tipy

Pokud se rozhodnete využít framework Bootstrap pro tvorbu responzivních webových rozhraní, je důležité správně pochopit, jak fungují kontejnery, řádky, sloupce, témata barev a komponenty jako tabulky, tlačítka a upozornění. Tento nástroj nabízí širokou paletu možností, jak ulehčit vývoj a zjednodušit tvorbu moderního webu. Důležité je ale mít na paměti správné použití těchto komponent pro dosažení optimálních výsledků.

Bootstrap nabízí flexibilní systém rozvržení pomocí kontejnerů. Kontejnery, jako container-lg a container-fluid, hrají klíčovou roli při definování šířky obsahu na stránce. Pokud použijete container-fluid, jeho šířka vždy odpovídá 100 % šířky prohlížeče, zatímco u container-lg při šířce nad 992 pixelů se šířka přizpůsobuje na hodnoty 960 px, 1140 px nebo 1320 px podle velikosti obrazovky.

Rozdělení stránek na řádky a sloupce je dalším důležitým prvkem frameworku. Bootstrap rozděluje obsah do 12 virtuálních sloupců. Pokud použijete třídu col, každý sloupec bude mít rovnoměrně rozdělenou šířku. Při definování konkrétního počtu sloupců (například 2/12 pro levý sloupec a 4/12 pro pravý) můžete přesně určit, jak se bude obsah rozkládat. I když je systém rozvržení velmi silný, může být složitý při složitějších strukturách. Vždy je tedy dobré mít na paměti flexibilitu a přizpůsobivost těchto komponent pro konkrétní potřeby.

Pokud jde o designové možnosti, Bootstrap nabízí osm vestavěných barevných témat, jako jsou „primary“ (jasně modrá), „secondary“ (šedá), „success“ (zelená) nebo „danger“ (červená), které vám umožní rychle měnit vzhled vašeho webu. Každé z těchto témat lze použít pro pozadí, text a okraje, což zjednodušuje ladění vizuální stránky. Tato témata jsou ideální pro zajištění konzistentního designu bez nutnosti psaní vlastního CSS kódu.

Tabulky v Bootstrapu nejsou automaticky stylizovány. Pro jejich použití musíte přidat třídu table, a následně můžete přizpůsobit vzhled tabulky pomocí dalších tříd, jako jsou table-striped pro zebrování řádků nebo table-bordered pro přidání okrajů. Třídy jako table-sm pak umožní vytvoření kompaktní verze tabulky s menším vycpáváním. Pokud chcete, aby obsah buněk tabulky byl zarovnán jinak, můžete použít třídy jako align-top, align-middle nebo align-bottom pro vertikální zarovnání nebo align-left, align-right pro horizontální.

Pro zajištění interaktivity na stránkách Bootstrap poskytuje celou řadu komponent, mezi které patří tlačítka a odkazy. Tyto komponenty mohou mít různý vzhled, který se přizpůsobí podle zvolené třídy. Například tlačítka s třídou btn-outline-primary budou mít bílý podklad a barevné obrysy, které se při najetí kurzorem změní na plný barevný výplň. Tlačítka lze dále upravit pomocí tříd jako btn-sm pro menší velikost nebo btn-lg pro větší. Badge komponenty zase umožňují zobrazovat malé informace, jako například počet nepřečtených zpráv, a mohou mít zaoblené okraje pro vytvoření "pille" stylu.

Pro zobrazení upozornění návštěvníkům webu můžete použít komponentu „alerts“, která je kompatibilní s výše zmíněnými barevnými tématy. Tyto alerty mohou obsahovat nejen text, ale i další HTML prvky, například odkazy, které je možné stylizovat pomocí třídy alert-link. Pokud chcete zvýraznit určitý typ upozornění, např. úspěšné objednávky nebo chyby, můžete využít různé barvy, jako jsou „success“ (zelená) pro úspěch, nebo „danger“ (červená) pro chyby.

Bootstrap je open-source, dobře dokumentovaný a vysoce přizpůsobitelný nástroj, který může zásadně urychlit vývoj webových stránek. Důvodem, proč jej používá tolik vývojářů, je nejen úspora času při tvorbě responzivního rozhraní, ale také široká podpora komunity a snadnost integrace s moderními webovými aplikacemi. Nicméně při jeho používání je důležité mít na paměti jeho možná omezení a složitost při použití složitějších rozvržení a komponent.

Pokud se rozhodnete používat Bootstrap, doporučuje se také přizpůsobit jeho výchozí styly podle konkrétních potřeb projektu. Někdy je totiž lepší přidat vlastní CSS pro určité detaily vzhledu, aby váš web měl jedinečný a originální vzhled. Samozřejmě, že pokud jde o rychlost vývoje a úsporu času, Bootstrap je ideálním nástrojem pro většinu běžných webových projektů.

Jak vytvořit a testovat komponenty Blazor pro webové aplikace

Při vývoji webových aplikací s použitím Blazor WebAssembly se stává vytváření interaktivních komponent nezbytným krokem pro zajištění kvalitní uživatelské zkušenosti. V této kapitole se podíváme na několik příkladů, jak vytvořit a otestovat Blazor komponenty, které využívají technologii WebAssembly pro dynamickou interakci s uživatelem.

Začneme jednoduchou komponentou pro zobrazení vývojového procesu simulovaného mazání databáze. Poté se zaměříme na komponenty pro zobrazení dialogových oken a alertů, které mohou být integrovány do jakékoli Blazor aplikace.

Simulace pokroku při mazání databáze

Představte si, že vytváříte webovou aplikaci, která umožňuje uživatelům smazat databázi. V rámci tohoto procesu můžeme využít Blazor WebAssembly k vytvoření vizuální indikace pokroku operace. Tento indikátor bude zobrazovat průběh (simulovaný) procesu mazání a poskytne uživateli informaci o stavu operace.

Začněte tím, že v souboru App.razor zakomentujete příslušný element, který zajistí, že daný prvek nebude zobrazen, jak je uvedeno v následujícím kódu. Tato úprava umožňuje, že při používání čtečky obrazovky bude oznámeno, že stránka je navigována, ale zároveň se vyhnete vizuálně neatraktivnímu efektu.

Pokud zahájíte projekt Northwind.BlazorWasm.Server a použijete profil HTTPS bez ladění, uvidíte progress bar, který bude ukazovat simulovaný pokrok mazání databáze, jak je znázorněno na obrázku 16.2.

Vytváření komponenty pro dialogová okna

Blazor také umožňuje snadno vytvářet modální okna pro interakci s uživatelem. V tomto příkladu vytvoříme komponentu pro zobrazení jednoduchého dialogového okna, které bude obsahovat dva tlačítka. Tento dialog bude konfigurovatelný a umožní rodičovskému komponentu přizpůsobit texty tlačítek a akce prováděné při kliknutí na ně.

Začněte tím, že přidáte nový soubor DialogBox.razor do složky Components v projektu Northwind.BlazorWasm.Client. V souboru použijete Bootstrap třídy k definování tlačítek a modálního okna, jak je ukázáno v následujícím kódu:

razor
<DialogTitle>@DialogTitle</DialogTitle> <ChildContent> <button @onclick="OnClickPrimary">@PrimaryButtonText</button> <button @onclick="OnClickSecondary">@SecondaryButtonText</button> </ChildContent> @code { [Parameter] public string? DialogTitle { get; set; } [Parameter] public RenderFragment? ChildContent { get; set; } [Parameter] public string? PrimaryButtonText { get; set; } = "OK"; [Parameter] public EventCallback OnClickPrimary { get; set; } [Parameter] public string? SecondaryButtonText { get; set; } = "Cancel"; [Parameter] public EventCallback OnClickSecondary { get; set; } }

Tento kód umožňuje zobrazení modálního okna s tlačítky, které mají výchozí texty „OK“ a „Cancel“. Po kliknutí na tlačítka je zajištěna komunikace s rodičovským komponentem pomocí event callbacků.

Příklad na stránce Index.razor zobrazuje, jak tuto komponentu použít v aplikaci, kde se například ptáme uživatele, zda chce smazat databázi. Na základě toho, jaký tlačítko uživatel klikne, se vypíše odpovídající zpráva do konzole.

razor
<DialogBox DialogTitle="Are you sure you want to delete the entire database?"
PrimaryButtonText="Yes" SecondaryButtonText="No" OnClickPrimary="Yes_Click" OnClickSecondary="No_Click"> </DialogBox>

V metodách Yes_Click a No_Click můžete například zaznamenávat polohu kurzoru na obrazovce, jak je uvedeno v následujícím kódu:

razor
private void Yes_Click(MouseEventArgs e) { Console.WriteLine("User clicked 'Primary' button at ({0}, {1}).", e.ClientX, e.ClientY); } private void No_Click(MouseEventArgs e) { Console.WriteLine("User clicked 'Secondary' button at ({0}, {1}).", e.ClientX, e.ClientY); }

Vytváření komponenty pro zobrazení alertů

Další užitečnou komponentou je Alert, která umožňuje zobrazovat barevné zprávy, jež mohou být zavřeny uživatelem. Tato komponenta používá Bootstrap třídy k definování stylu a ikon pro různé typy zpráv. Uživatel může snadno přizpůsobit barvu, ikonu i text, který je zobrazen ve zprávě.

Pro implementaci této komponenty vytvořte v projektu Northwind.BlazorWasm.Shared třídu s názvem BootstrapColors a BootstrapIcons, která bude obsahovat předdefinované hodnoty pro barvy a ikony používané v Bootstrapu. Tato třída pak bude sloužit pro konfiguraci komponenty alertu.

csharp
public static class BootstrapColors {
public const string Primary = "primary";
public const string Success = "success";
public const string Danger = "danger";
public const string Warning = "warning";
public const string Info = "info"; } public static class BootstrapIcons { public const string Info = "bi-info";
public const string Check = "bi-check-circle";
public const string Warning = "bi-exclamation-triangle";
public const string Error = "bi-x-circle";
}

Použitím těchto tříd v komponentě alertu, můžete snadno konfigurovat barvu a ikonu zprávy, což umožní její přizpůsobení potřebám aplikace.

Důležité poznámky

Při práci s Blazor WebAssembly je nutné mít na paměti, že i když technologie umožňuje vytváření komplexních interaktivních aplikací, uživatelé s pomalejšími připojeními k internetu mohou zaznamenat zpoždění v načítání a vykreslování komponent. Proto je důležité optimalizovat aplikace tak, aby minimalizovaly tento vliv.

Kromě toho, při návrhu interakce s uživatelem je třeba vždy zvažovat přístupnost aplikace. Použití obrazovkových čteček, správné ohlášení změn stavu (například při navigaci nebo interakci s dialogovými okny) by mělo být standardem pro každého vývojáře Blazor aplikací.

Jak implementovat mutace v GraphQL pro správu produktů

Při práci s GraphQL se často setkáváme s potřebou nejen číst data, ale také je upravovat. V tomto případě si ukážeme, jak vytvořit mutaci pro přidání nového produktu do databáze, což je běžný scénář ve vývoji aplikací, které pracují s produktovými daty. Při implementaci GraphQL mutace je klíčové pochopit, jakým způsobem definujeme operace pro změnu stavu dat a jak je implementujeme v konkrétním jazyce a frameworku.

Mutace v GraphQL slouží k provádění operací, které mění data. Na rozdíl od dotazů (queries), které pouze čtou data, mutace zahrnují operace jako přidání, aktualizace nebo smazání dat. Mutace mohou mít vstupy, které specifikují data, jež budou použita v operaci, a výstupy, které určují, co vrátí server po provedení operace.

V našem příkladu budeme implementovat mutaci pro přidání nového produktu do databáze. Nejprve musíme definovat vstupy pro tuto mutaci. Vstupy specifikují, jaké parametry budou použity k vytvoření nového produktu, například název produktu, cena za jednotku, množství na skladě a další relevantní údaje.

csharp
public record AddProductInput( string ProductName, int? SupplierId, int? CategoryId, string QuantityPerUnit, decimal? UnitPrice, short? UnitsInStock, short? UnitsOnOrder, short? ReorderLevel, bool Discontinued);

V tomto záznamu (record) specifikujeme všechny parametry, které potřebujeme pro přidání nového produktu. Parametry jako SupplierId, CategoryId nebo UnitPrice jsou volitelné, což znamená, že je možné je nevyplnit, ale přesto budou moci být použity, pokud budou dostupné.

Poté musíme definovat třídu pro výstup, který bude obsahovat objekt produktu, jenž byl právě přidán do databáze:

csharp
public class AddProductPayload { public AddProductPayload(Product product) { Product = product; } public Product Product { get; } }

Třída AddProductPayload je obalová třída, která vrací přidaný produkt jako výstup mutace.

V dalším kroku implementujeme samotnou mutaci v GraphQL. Tato mutace bude přijímat vstupy typu AddProductInput a na základě těchto vstupů vytvoří nový produkt v databázi. Výsledek bude obalen do objektu AddProductPayload:

csharp
public class Mutation {
public async Task<AddProductPayload> AddProductAsync(AddProductInput input, NorthwindContext db) { Product product = new() { ProductName = input.ProductName, SupplierId = input.SupplierId, CategoryId = input.CategoryId, QuantityPerUnit = input.QuantityPerUnit, UnitPrice = input.UnitPrice, UnitsInStock = input.UnitsInStock, UnitsOnOrder = input.UnitsOnOrder, ReorderLevel = input.ReorderLevel, Discontinued = input.Discontinued }; db.Products.Add(product); int affectedRows = await db.SaveChangesAsync(); return new AddProductPayload(product); } }

Tato metoda přijímá vstupy, vytváří nový produkt a uloží ho do databáze. Po provedení operace vrací nový objekt AddProductPayload s právě přidaným produktem.

Další krok spočívá v registraci mutace v GraphQL serveru. V souboru Program.cs je potřeba přidat registraci mutace:

csharp
builder.Services
.AddGraphQLServer() .RegisterDbContext() .AddQueryType() .AddMutationType();

Tímto způsobem registrujeme naši mutaci pro přidání produktu, která je následně dostupná na serveru. Nyní si můžeme vyzkoušet volání této mutace.

Ve nástroji Banana Cake Pop (nástroj pro práci s GraphQL) můžeme definovat mutaci pro přidání nového produktu. Následující kód ukazuje, jak vypadá samotné volání mutace pro přidání produktu s názvem „Tasty Burgers“:

graphql
mutation AddProduct { addProduct( input: { productName: "Tasty Burgers" supplierId: 1 categoryId: 2 quantityPerUnit: "6 per box" unitPrice: 40 unitsInStock: 0 unitsOnOrder: 0 reorderLevel: 0 discontinued: false } ) { product { productId productName } } }

Tato mutace přidá nový produkt s názvem „Tasty Burgers“ do databáze a vrátí informace o přidaném produktu, včetně jeho ID a názvu.

Po provedení mutace můžeme vidět odpověď, která potvrzuje úspěšné přidání produktu:

json
{
"data": { "addProduct": { "product": { "productId": 79, "productName": "Tasty Burgers" } } } }

Je důležité si uvědomit, že GraphQL mutace nejenom že přidávají data do databáze, ale mohou také vracet různé typy dat podle toho, co je definováno ve schématu. V tomto případě jsme definovali, že po přidání produktu se vrátí objekt produktu, což nám umožňuje ihned pracovat s těmito novými daty, aniž bychom museli provádět další dotazy.

Mutace v GraphQL jsou velmi silným nástrojem pro správu dat na serveru. Pokud správně využijete mutace ve vaší aplikaci, můžete s jejich pomocí efektivně měnit stav aplikace a pracovat s daty, aniž byste museli řešit složitou logiku pro komunikaci mezi klientem a serverem. Ať už jde o přidávání produktů, aktualizaci informací o objednávkách nebo jakékoliv jiné operace, mutace vám poskytnou silný základ pro tvorbu dynamických a interaktivních aplikací.