vývoj aplikací ASP.NET Core MVC
"Není důležité si ho poprvé napravit. Je důležité, abyste si ho v poslední době získali hned. " – Andrew loven a David Tomáš
ASP.NET Core je open source platforma pro různé platformy pro vytváření moderních cloudových webových aplikací. aplikace ASP.NET Core jsou odlehčené a modulární s integrovanou podporou pro vkládání závislostí a umožňují větší možnosti testování a udržovatelnosti. v kombinaci se službou MVC, která kromě aplikací založených na zobrazení podporuje vytváření moderních webových rozhraní api, ASP.NET Core představuje výkonnou architekturu pro vytváření podnikových webových aplikací.
MVC a Razor Pages
ASP.NET Core MVC nabízí mnoho funkcí, které jsou užitečné při vytváření webových rozhraní API a aplikací. Termín MVC představuje "Model-View-Controller", vzorek uživatelského rozhraní, který rozdělí zodpovědnosti na požadavky uživatelů na několik částí. kromě tohoto vzoru můžete ve svých aplikacích pro ASP.NET Core taky implementovat funkce jako Razor Pages. Razor Pages jsou integrované do ASP.NET Core MVC a používají stejné funkce pro směrování, vázání modelů, filtry, autorizaci atd. Místo toho, aby byly samostatné složky a soubory pro řadiče, modely, zobrazení atd. a používaly směrování založené na atributech, Razor Pages jsou umístěny do jediné složky ("/Pages"), směrovat na základě jejich relativního umístění v této složce a zpracovávat požadavky pomocí obslužných rutin namísto akcí kontroleru. Výsledkem je, že při práci s Razor Pages jsou všechny soubory a třídy, které potřebujete, obvykle společně umístěny, nikoli rozloženy do celého webového projektu.
když vytváříte novou aplikaci ASP.NET Core, měli byste mít na paměti, že máte na mysli druh aplikace, kterou chcete sestavit. v Visual Studio vyberete z několika šablon. Tři nejběžnější šablony projektu jsou webové rozhraní API, Webová aplikace a webová aplikace (Model-View-Controller). I když můžete toto rozhodnutí udělat pouze při prvním vytvoření projektu, není to neodvolatelné rozhodnutí. Projekt webového rozhraní API používá standardní řadiče pro zobrazení modelu, ale ve výchozím nastavení jen postrádá zobrazení. Stejně tak výchozí šablona webové aplikace používá Razor Pages, a tak také nemá složku zobrazení. Do těchto projektů můžete přidat složku zobrazení později, aby se podporovalo chování na základě zobrazení. Projekty webového rozhraní API a Model-View-Controller ve výchozím nastavení neobsahují složku Pages, ale můžete ji přidat později, aby se podporovalo chování založené na Razor Pages. Tyto tři šablony si můžete představit jako podpora tří různých druhů výchozích zásahů uživatele: data (webové rozhraní API), na stránce a na základě zobrazení. V případě potřeby však můžete v rámci jednoho projektu kombinovat a porovnat libovolné nebo všechny tyto šablony.
Proč Razor Pages?
Razor Pages je výchozím přístupem pro nové webové aplikace v Visual Studio. Razor Pages nabízí jednodušší způsob, jak sestavovat funkce aplikace založené na stránkách, jako jsou například formuláře bez hesla. Pomocí řadičů a zobrazení je běžné, že aplikace mají velmi velké řadiče, které pracovaly s mnoha různými závislostmi a zobrazují modely a vracejí mnoho různých zobrazení. Výsledkem je složitější a často se jedná o řadiče, které nesledovaly princip jedné zodpovědnosti nebo efektivně otevřené nebo uzavřené zásady. Tento problém Razor Pages řeší zapouzdřením logiky na straně serveru pro danou logickou "stránku" v rámci webové aplikace pomocí značek Razor. Stránka Razor, která nemá žádnou logiku na straně serveru, může obsahovat pouze soubor Razor (například index. cshtml). Ale většina netriviálních Razor Pages bude mít přidruženou třídu modelu stránky, která je podle konvence pojmenována stejně jako soubor Razor s příponou. cs (například index. cshtml. cs).
Model stránky stránky Razor kombinuje zodpovědnosti kontroleru MVC a ViewModel. Místo zpracování žádostí s metodami akce kontroleru se spustí obslužné rutiny modelu stránky, jako je například "OnGet ()", vykreslení jejich přidružené stránky ve výchozím nastavení. Razor Pages zjednodušuje proces sestavování jednotlivých stránek v aplikaci ASP.NET Core a zároveň stále poskytuje všechny funkce architektury služby ASP.NET Core MVC. Jsou to dobrá výchozí volba pro nové funkce založené na stránkách.
Kdy použít MVC
Pokud vytváříte webová rozhraní API, vzor MVC je větší, než se snažíte použít Razor Pages. Pokud váš projekt zveřejňuje koncové body webového rozhraní API, měli byste v ideálním případě začít od šablony projektu webového rozhraní API. v opačném případě je snadné přidat řadiče a přidružené koncové body rozhraní API do libovolné ASP.NET Core aplikace. přístup na základě zobrazení mvc můžete použít, pokud migrujete existující aplikaci z ASP.NET mvc 5 nebo starší na ASP.NET Core MVC a chcete tak učinit s minimálním úsilím. Po provedení prvotní migrace můžete vyhodnotit, jestli má smysl přijmout Razor Pages pro nové funkce nebo dokonce i jako migraci ve velkoobchodu.
Bez ohledu na to, jestli se rozhodnete vytvořit webovou aplikaci pomocí Razor Pages nebo zobrazení MVC, bude mít aplikace podobný výkon a bude zahrnovat podporu pro vkládání závislostí, filtry, vázání modelů, ověřování atd.
Mapování požadavků na odpovědi
ve své srdci ASP.NET Core aplikace mapují příchozí požadavky na odchozí odpovědi. na nízké úrovni se toto mapování provádí pomocí middlewaru a jednoduché ASP.NET Core aplikace a mikroslužby mohou obsahovat pouze vlastní middleware. při použití ASP.NET Core MVC můžete pracovat na trochu vyšší úrovni, což je v souladu s trasami, řadiči a akcemi. Každý příchozí požadavek je porovnán s tabulkou směrování aplikace a pokud je nalezena odpovídající trasa, je pro zpracování žádosti volána přidružená metoda akce (patří k řadiči). Pokud není nalezena žádná vyhovující trasa, je volána obslužná rutina chyby (v tomto případě vrátí výsledek NotFound).
ASP.NET Core Aplikace MVC můžou používat konvenční trasy, trasy atributů nebo obojí. Konvenční trasy jsou definovány v kódu a určují konvence směrování pomocí syntaxe jako v následujícím příkladu:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});
V tomto příkladu byla do směrovací tabulky přidána trasa s názvem "default". Definuje šablonu směrování se zástupnými symboly pro controller , action a id . controller action Zástupné symboly a mají zadanou výchozí hodnotu ( Home a Index ) a id zástupný symbol je nepovinný (na základě použití "?"). Zde definovaná konvence uvádí, že první část požadavku by měla odpovídat názvu kontroleru, druhé části akce a v případě, že je potřeba třetí část, bude představovat parametr ID. Konvenční trasy jsou obvykle definovány na jednom místě pro aplikaci, například v Configure metodě ve Startup třídě.
Trasy atributů jsou aplikovány přímo na řadiče a akce namísto zadání globálně. Tento přístup má výhodu, že je mnohem více zjistitelných, když se díváte na konkrétní metodu, ale znamená, že informace o směrování nejsou uchovávány na jednom místě v aplikaci. Pomocí tras atributů můžete snadno zadat více tras pro danou akci a kombinovat trasy mezi řadiči a akcemi. Například:
[Route("Home")]
public class HomeController : Controller
{
[Route("")] // Combines to define the route template "Home"
[Route("Index")] // Combines to define route template "Home/Index"
[Route("/")] // Does not combine, defines the route template ""
public IActionResult Index() {}
}
Trasy lze zadat na [HttpGet] a podobných atributech a vyhnout se nutnosti přidávat samostatné atributy [Route]. Trasy atributů můžou také používat tokeny k omezení nutnosti opakovat názvy kontroléru nebo akce, jak je znázorněno níže:
[Route("[controller]")]
public class ProductsController : Controller
{
[Route("")] // Matches 'Products'
[Route("Index")] // Matches 'Products/Index'
public IActionResult Index() {}
}
Razor Pages nepoužívá směrování atributů. V rámci své směrnice můžete zadat další informace o šabloně směrování pro stránku Razor @page :
@page "{id:int}"
V předchozím příkladu by se stránka měla shodovat s id parametrem typu Integer. Například stránka Products. cshtml , která se nachází v kořenovém adresáři, /Pages by měla tuto trasu:
"/Products/123"
po porovnání dané žádosti s trasou, ale před zavoláním metody action, ASP.NET Core MVC provede vazbu modelu a ověření modelu na žádosti. Vazba modelu zodpovídá za převod příchozích dat HTTP do typů .NET určených jako parametrů metody akce, která má být volána. Například pokud metoda Action očekává int id parametr, vazba modelu se pokusí poskytnout tento parametr z hodnoty zadané v rámci žádosti. V takovém případě vazba modelu vyhledá hodnoty v zaúčtovaném formuláři, hodnotách v samotné trase a hodnotách řetězce dotazu. Za předpokladu id , že je hodnota nalezena, bude před předáním do metody Action převedena na celé číslo.
Po vytvoření vazby modelu, ale před voláním metody Action, dojde k ověření modelu. Ověřování modelu používá volitelné atributy pro typ modelu a může zajistit, aby zadaný objekt modelu splňoval určité požadavky na data. Některé hodnoty mohou být zadány jako povinné nebo omezené na určitou délku nebo číselný rozsah atd. Pokud jsou zadány atributy ověřování, ale model nevyhovuje jejich požadavkům, vlastnost ModelState. IsValid bude false a sada neúspěšných ověřovacích pravidel bude k dispozici pro odeslání klientovi, který vytváří požadavek.
Pokud používáte ověřování modelu, měli byste před provedením jakýchkoli příkazů pro změnu stavu zkontrolovat, jestli je model platný, abyste zajistili, že vaše aplikace nebude poškozená pomocí neplatných dat. Filtr můžete použít k tomu, abyste se vyhnuli nutnosti přidat kód pro toto ověření při každé akci. ASP.NET Core Filtry MVC nabízejí způsob, jak zachytit skupiny požadavků, aby bylo možné použít společné zásady a vzájemné navýšení obav na základě cíle. Filtry lze použít pro jednotlivé akce, pro všechny řadiče nebo pro globálně pro aplikaci.
pro webová rozhraní api ASP.NET Core MVC podporuje vyjednávání obsahua umožňuje žádostem určit, jak mají být odpovědi naformátovány. V závislosti na hlavičkách poskytnutých v žádosti naformátují akce vracející data odpověď ve formátu XML, JSON nebo v jiném podporovaném formátu. Tato funkce umožňuje používat stejné rozhraní API pro více klientů s různými požadavky na formát dat.
Projekty webového rozhraní API by měly uvažovat o použití [ApiController] atributu, který lze použít na jednotlivé řadiče, na základní třídu kontroleru nebo na celé sestavení. Tento atribut přidá automatickou kontrolu ověřování modelu a všechny akce s neplatným modelem vrátí důvodu chybného požadavku s podrobnostmi o chybách ověřování. Atribut také vyžaduje, aby všechny akce měly trasu atributu, nikoli použití konvenční trasy, a v reakci na chyby vrátí podrobnější informace ProblemDetails.
Udržování řadičů pod kontrolou
Pro aplikace založené na stránkách Razor Pages udělejte skvělou úlohu udržování příliš velkých řadičů. Na každou jednotlivou stránku jsou přiděleny vlastní soubory a třídy, které jsou vyhrazeny pouze jeho obslužným rutinám. Před zavedením Razor Pages mají mnoho aplikací orientovaných na zobrazení velké třídy řadiče zodpovědné za mnoho různých akcí a zobrazení. Tyto třídy by přirozeně vzrostly tak, aby měly mnoho zodpovědností a závislostí, což ztěžuje jejich udržení. Pokud zjistíte, že vaše řadiče založené na zobrazení jsou příliš velké, zvažte jejich refaktoring, aby používaly Razor Pages, nebo zavedený vzor jako zprostředkovatel.
Vzor návrhu prostředníku se používá ke snížení spojení mezi třídami a současně umožňuje komunikaci mezi nimi. v ASP.NET Corech aplikacích MVC je tento vzor často zaměstnán pro rozdělení řadičů do menších částí pomocí obslužných rutin k provedení práce s metodami akcí. k tomuto účelu se často používá oblíbený balíček MediatR NuGet . Řadiče obvykle obsahují mnoho různých metod akcí, z nichž každá může vyžadovat určité závislosti. Sada všech závislostí vyžadovaných všemi akcemi musí být předána do konstruktoru kontroleru. Při použití MediatR je jedinou závislostí řadiče na instanci prostředníka. Každá akce poté používá instanci prostředníka k odeslání zprávy, která je zpracována obslužnou rutinou. Obslužná rutina je specifická pro jednu akci, takže potřebuje jenom závislosti, které tato akce vyžaduje. Příklad kontroleru s použitím MediatR se zobrazí tady:
public class OrderController : Controller
{
private readonly IMediator _mediator;
public OrderController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet]
public async Task<IActionResult> MyOrders()
{
var viewModel = await _mediator.Send(new GetMyOrders(User.Identity.Name));
return View(viewModel);
}
// other actions implemented similarly
}
V MyOrders akci Send je volání GetMyOrders zprávy zpracováno touto třídou:
public class GetMyOrdersHandler : IRequestHandler<GetMyOrders, IEnumerable<OrderViewModel>>
{
private readonly IOrderRepository _orderRepository;
public GetMyOrdersHandler(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
public async Task<IEnumerable<OrderViewModel>> Handle(GetMyOrders request, CancellationToken cancellationToken)
{
var specification = new CustomerOrdersWithItemsSpecification(request.UserName);
var orders = await _orderRepository.ListAsync(specification);
return orders.Select(o => new OrderViewModel
{
OrderDate = o.OrderDate,
OrderItems = o.OrderItems?.Select(oi => new OrderItemViewModel()
{
PictureUrl = oi.ItemOrdered.PictureUri,
ProductId = oi.ItemOrdered.CatalogItemId,
ProductName = oi.ItemOrdered.ProductName,
UnitPrice = oi.UnitPrice,
Units = oi.Units
}).ToList(),
OrderNumber = o.Id,
ShippingAddress = o.ShipToAddress,
Total = o.Total()
});
}
}
Konečný výsledek tohoto přístupu je, aby řadiče byly mnohem menší a zaměřené hlavně na směrování a vázání modelů, zatímco jednotlivé obslužné rutiny jsou zodpovědné za konkrétní úkoly vyžadované daným koncovým bodem. tento přístup je možné dosáhnout i bez MediatR pomocí balíčku ApiEndpoints NuGet, který se pokusí přenést do řadičů API stejné výhody, Razor Pages přináší na řadiče na základě zobrazení.
Odkazy – mapování požadavků na odpovědi
- Směrování na akce kontroleru
https://docs.microsoft.com/aspnet/core/mvc/controllers/routing- Vazba modelu
https://docs.microsoft.com/aspnet/core/mvc/models/model-binding- Ověření modelu
https://docs.microsoft.com/aspnet/core/mvc/models/validation- Outlook
https://docs.microsoft.com/aspnet/core/mvc/controllers/filters- ApiController – atribut
https://docs.microsoft.com/aspnet/core/web-api/
Práce se závislostmi
ASP.NET Core má integrovanou podporu pro a interně využívá techniku známou jako vkládání závislostí. Injektáže závislostí je technika, která umožňuje volné spojení mezi různými částmi aplikace. Volné spojení je žádoucí, protože usnadňuje izolaci částí aplikace a umožňuje jejich testování nebo nahrazení. Tím je také méně pravděpodobný, že změna v jedné části aplikace bude mít neočekávaný dopad někde jinde v aplikaci. Vstřik závislosti je založen na principu inverze závislosti a často se jedná o klíč k dosažení principu otevření/uzavření. Při vyhodnocování, jak vaše aplikace pracuje s jejími závislostmi, si popamatujete pach kódu statického cling a zapamatujte si, že aphorism "nové je připevnit".
Ke statickému cling dochází, když vaše třídy volají volání statických metod, nebo mají přístup ke statickým vlastnostem, které mají vedlejší účinky nebo závislosti na infrastruktuře. Například pokud máte metodu, která volá statickou metodu, která zase zapisuje do databáze, vaše metoda je pevně spojena s databází. Cokoli, co toto volání databáze přeruší, bude vaše metoda rušit. Testování takových metod je obvykle odlaďuje obtížné, protože tyto testy buď vyžadují komerční napodobné knihovny pro napodobení statických volání, nebo je lze testovat pouze pomocí testovací databáze na místě. Statická volání, která nemají žádnou závislost na infrastruktuře, zejména tato volání, která jsou zcela Bezstavová, jsou schopná volat a nemají žádný vliv na spojení ani možnosti testování (nad spojovým kódem samotným statickým voláním).
Mnoho vývojářů rozumí rizikům statických cling a globálních stavů, ale stále úzce přiděluje svůj kód na konkrétní implementace prostřednictvím přímé instance. "Nové je připevnit", aby bylo připomenutí tohoto spoje, a ne obecné condemnation použití new klíčového slova. Stejně jako u volání statických metod nové instance typů, které nemají žádné externí závislosti, obvykle nezpůsobí pevnění kódu k implementačním podrobnostem nebo provádění testování obtížnější. Ale pokaždé, když je vytvořena instance třídy, posuzuje, zda má smysl na pevný kód konkrétní instance v daném umístění, nebo v případě, že by byl lepším návrhem pro vyžádání této instance jako závislosti.
Deklarovat závislosti
ASP.NET Core je sestaven s ohledem na to, že metody a třídy deklaruje jejich závislosti, a požaduje je jako argumenty. ASP.NET aplikace se obvykle nastavují ve spouštěcí třídě, která je nakonfigurovaná tak, aby podporovala vkládání závislostí na několika místech. Pokud má vaše spouštěcí třída konstruktor, může vyžádat závislosti prostřednictvím konstruktoru, například takto:
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
}
}
Spouštěcí třída je zajímavá v tom, že pro ni nejsou k dispozici žádné explicitní požadavky typu. Nedědí ze speciální spouštěcí základní třídy ani neimplementuje žádné konkrétní rozhraní. Můžete mu udělit konstruktor nebo ne a můžete zadat tolik parametrů v konstruktoru, jak chcete. Po spuštění webového hostitele, který jste nakonfigurovali pro vaši aplikaci, bude volat spouštěcí třídu, kterou jste si dozvěděli, že se má použít, a pomocí injektáže závislosti vyplníte všechny závislosti, které spouštěcí třída vyžaduje. samozřejmě, pokud požadujete parametry, které nejsou nakonfigurované v kontejneru services používaném ASP.NET Core, získáte výjimku, ale pokud budete chtít, aby se na závislosti kontejneru ví, můžete si vyžádat cokoli, co potřebujete.
vkládání závislostí je v aplikacích ASP.NET Core přímo od spuštění, když vytváříte instanci spouštění. Neukončí třídu pro spuštění. V metodě konfigurace můžete také vyžádat závislosti:
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
}
Metoda ConfigureServices je výjimkou tohoto chování; musí mít pouze jeden parametr typu IServiceCollection. Ve skutečnosti nemusí podporovat vkládání závislostí, protože na jedné straně zodpovídá za přidání objektů do kontejneru služeb a na druhé má přístup ke všem aktuálně nakonfigurovaným službám prostřednictvím parametru IServiceCollection. proto můžete pracovat se závislostmi definovanými v kolekci ASP.NET Core services v každé části třídy po spuštění, a to tak, že požadujete potřebnou službu jako parametr nebo při práci s IServiceCollection v ConfigureServices.
Poznámka
Pokud potřebujete zajistit, aby byly určité služby k dispozici pro třídu pro spuštění, můžete je nakonfigurovat pomocí IWebHostBuilder a její ConfigureServices metody uvnitř volání CreateDefaultBuilder.
spouštěcí třída je modelem, jak byste měli strukturovat ostatní části aplikace ASP.NET Core, od řadičů po middlewaru až po filtrování na vaše vlastní služby. V každém případě byste měli postupovat podle principu explicitních závislostí, vyžádat si své závislosti namísto jejich přímého vytváření a využití injektáže závislostí v celé aplikaci. Buďte opatrní, kde a jak přímo vytvářet instance implementací, zejména služeb a objektů, které pracují s infrastrukturou nebo mají vedlejší účinky. Preferovat práci s abstrakcemi definovanými v jádru vaší aplikace a předanými jako argumenty pro zakódujeme odkazů na konkrétní typy implementace.
Strukturování aplikace
Monolitické aplikace mají typicky jeden vstupní bod. v případě ASP.NET Core webové aplikace bude vstupním bodem ASP.NET Core webový projekt. To však neznamená, že by se mělo řešení sestávat pouze z jednoho projektu. Je vhodné rozdělit aplikaci do různých vrstev, aby bylo možné postupovat podle oddělení obav. Po rozčlenění do vrstev je vhodné přecházet mimo složky pro samostatné projekty, což může pomoct dosáhnout lepšího zapouzdření. nejlepším způsobem, jak dosáhnout těchto cílů pomocí ASP.NET Core aplikace, je variace čisté architektury popsané v kapitole 5. Po tomto přístupu bude řešení aplikace zahrnovat samostatné knihovny pro uživatelské rozhraní, infrastrukturu a ApplicationCore.
Kromě těchto projektů jsou zahrnuty také samostatné testovací projekty (testování je popsáno v kapitole 9).
Objektový model a rozhraní aplikace by měly být umístěny do projektu ApplicationCore. Tento projekt bude mít co nejmenší závislosti a ostatní projekty v řešení na něj budou odkazovat. Obchodní entity, které je nutné zachovat, jsou definovány v projektu ApplicationCore, stejně jako služby, které nejsou přímo závislé na infrastruktuře.
Podrobnosti implementace, například jak probíhá trvalá trvalost nebo jak mohou být oznámení odeslána uživateli, jsou uchovávány v projektu infrastruktury. Tento projekt bude odkazovat na balíčky specifické pro implementaci, jako je například Entity Framework Core, ale neměly by zveřejňovat podrobnosti o těchto implementacích mimo projekt. Služby infrastruktury a úložiště by měly implementovat rozhraní, která jsou definovaná v projektu ApplicationCore, a jeho implementace trvalosti zodpovídá za načítání a ukládání entit definovaných v ApplicationCore.
projekt ASP.NET Core uživatelského rozhraní zodpovídá za všechny aspekty na úrovni uživatelského rozhraní, ale nemělo by obsahovat podrobnosti obchodní logiky nebo infrastruktury. V ideálním případě by neměl být v ideálním případě závislý na projektu infrastruktury, což vám pomůže zajistit, že nedojde k náhodnému zavedení žádné závislosti mezi těmito dvěma projekty. Toho lze dosáhnout pomocí kontejneru DI třetí strany, jako je Autofac, což umožňuje definovat pravidla DI v třídách modulů v každém projektu.
Dalším způsobem, jak odložení aplikace z podrobností implementace, je mít aplikace volající mikroslužby, případně nasazené v jednotlivých kontejnerech Docker. To poskytuje ještě větší oddělení obav a odpojuje se od využití DI mezi dvěma projekty, ale má další složitost.
Organizace funkcí
ve výchozím nastavení ASP.NET Core aplikace uspořádat svoji strukturu složek tak, aby zahrnovala řadiče a zobrazení a často ViewModels. Kód na straně klienta pro podporu těchto struktur na straně serveru je obvykle uložen samostatně ve složce Wwwroot. Velké aplikace ale můžou narazit na problémy s touto organizací, protože práce na určité funkci často vyžaduje přechod mezi těmito složkami. To znamená více a obtížnější, protože počet souborů a podsložek v každé složce roste a výsledkem je skvělé rolování prostřednictvím Průzkumník řešení. Jedním z řešení tohoto problému je organizovat kód aplikace podle funkcí , nikoli podle typu souboru. Tento styl organizace se obvykle označuje jako složky funkcí nebo řezy funkcí (viz také: svislé řezy).
ASP.NET Core MVC podporuje oblasti pro tento účel. Pomocí oblastí můžete vytvořit samostatné sady řadičů a složek zobrazení (stejně jako všechny přidružené modely) v každé složce oblasti. Obrázek 7-1 ukazuje příklad struktury složek s použitím oblastí.

Obrázek 7-1. Ukázková organizace oblastí
Při použití oblastí je nutné použít atributy k seupravování řadičů s názvem oblasti, do které patří:
[Area("Catalog")]
public class HomeController
{}
Také je potřeba přidat do svých tras podporu oblastí:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(name: "areaRoute", pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});
Kromě integrované podpory pro oblasti můžete také použít vlastní strukturu složek a konvence namísto atributů a vlastních tras. To vám umožní mít složky funkcí, které neobsahovaly samostatné složky pro zobrazení, řadiče atd., udržovat hierarchii plošší a zjednodušit zobrazení všech souvisejících souborů na jednom místě pro jednotlivé funkce.
ASP.NET Core používá k řízení jeho chování předdefinované typy konvencí. Tyto konvence můžete upravit nebo nahradit. Můžete například vytvořit konvenci, která automaticky získá název funkce pro daný řadič na základě jeho oboru názvů (který obvykle koreluje se složkou, ve které je kontroler umístěný):
public class FeatureConvention : IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
controller.Properties.Add("feature",
GetFeatureName(controller.ControllerType));
}
private string GetFeatureName(TypeInfo controllerType)
{
string[] tokens = controllerType.FullName.Split('.');
if (!tokens.Any(t => t == "Features")) return "";
string featureName = tokens
.SkipWhile(t => !t.Equals("features",
StringComparison.CurrentCultureIgnoreCase))
.Skip(1)
.Take(1)
.FirstOrDefault();
return featureName;
}
}
Tuto konvenci pak zadáte jako možnost při přidávání podpory pro MVC do aplikace v ConfigureServices:
services.AddMvc(o => o.Conventions.Add(new FeatureConvention()));
ASP.NET Core MVC také používá konvenci k vyhledání zobrazení. Můžete ho přepsat vlastní konvencí, aby se zobrazily ve složkách funkcí (pomocí názvu funkce poskytnutého FeatureConvention, výše). další informace o tomto přístupu a stažení pracovní ukázky najdete v článku na webu MSDN Magazine, řezy funkcí pro ASP.NET Core MVC.
Rozhraní API a Blazor aplikace
Pokud vaše aplikace obsahuje sadu webových rozhraní API, která musí být zabezpečená, měla by být tato rozhraní API v ideálním případě nakonfigurována jako samostatný projekt ze zobrazení nebo Razor Pages aplikace. Oddělení rozhraní API, zejména veřejných rozhraní API, z webové aplikace na straně serveru má řadu výhod. Tyto aplikace často budou mít jedinečné vlastnosti nasazení a zatížení. Také velmi pravděpodobně přijímají různé mechanismy zabezpečení a využívají standardní formulářové aplikace s využitím ověřování založeného na souborech cookie a rozhraní API, které nejpravděpodobněji využívají ověřování založené na tokenech.
Kromě toho Blazor musí být aplikace, ať už používají Blazor Server nebo Blazor WebAssembly , sestavené jako samostatné projekty. Aplikace mají různé běhové vlastnosti i modely zabezpečení. Budou pravděpodobně sdílet společné typy pomocí webové aplikace na straně serveru (nebo projektu rozhraní API) a tyto typy by měly být definovány v běžném sdíleném projektu.
Přidání Blazor WebAssembly rozhraní pro správu, které eShopOnWeb vyžaduje přidání několika nových projektů. Blazor WebAssembly Samotný projekt, BlazorAdmin . Nová sada veřejných koncových bodů rozhraní API, kterou používá BlazorAdmin a nakonfigurovali pro použití ověřování založeného na tokenech, je definována v PublicApi projektu. A některé sdílené typy používané oběma těmito projekty jsou uchovávány v novém BlazorShared projektu.
Může to vyžadovat, proč přidat samostatný BlazorShared projekt, pokud už existuje společný ApplicationCore projekt, který by se mohl použít ke sdílení libovolných typů vyžadovaných oběma i PublicApi BlazorAdmin ? Odpověď je v tom, že tento projekt obsahuje celou obchodní logiku aplikace a je tedy mnohem větší, než je nutné a je mnohem pravděpodobnější, že bude na serveru zabezpečeně zabezpečený. Pamatujte, že všechny knihovny, na které odkazuje, BlazorAdmin se stáhnou do prohlížečů uživatelů při načtení Blazor aplikace.
V závislosti na tom, jestli jedna používá vzor back-endy (BFF), nemusí rozhraní API spotřebovaná Blazor WebAssembly aplikací sdílet své typy 100% s Blazor . Konkrétně veřejné rozhraní API, které je určeno pro použití v mnoha různých klientech, může definovat vlastní typy požadavků a výsledků namísto jejich sdílení do sdíleného projektu specifického pro konkrétního klienta. Ve vzorku eShopOnWeb se předpokládá, že PublicApi projekt je ve skutečnosti hostující veřejné rozhraní API, takže ne všechny typy požadavků a odpovědí pocházejí z BlazorShared projektu.
Související aspekty
Jak aplikace roste, je stále důležitější, aby bylo možné vyloučit duplicity a zachovat konzistenci. mezi důležité aspekty průřezů v ASP.NET Core aplikacemi patří ověřování, pravidla ověřování modelů, ukládání výstupu do mezipaměti a zpracování chyb, i když existuje mnoho dalších. ASP.NET Core Filtry MVC umožňují spustit kód před nebo za některými kroky v kanálu zpracování požadavků. Filtr může například běžet před a po vazbě modelu, před a po akci, nebo před a po výsledku akce. Pomocí autorizačního filtru můžete také řídit přístup ke zbytku kanálu. Obrázky 7-2 ukazují, jak provádění požadavků prostřednictvím filtrů, pokud je nakonfigurováno.

Obrázek 7-2. Vyžádá provádění prostřednictvím filtrů a kanálu požadavků.
Filtry se obvykle implementují jako atributy, takže je můžete aplikovat na řadiče nebo akce (nebo i globálně). Při přidání tímto způsobem filtry zadané na úrovni akce přepisují nebo sestavují na filtrech zadaných na úrovni řadiče, které samy o nich přepíšou globální filtry. Například [ ] atribut Route lze použít k sestavení tras mezi řadiči a akcemi. Podobně je možné konfigurovat autorizaci na úrovni řadiče a pak je přepsat jednotlivými akcemi, jak ukazuje následující příklad:
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous] // overrides the Authorize attribute
public async Task<IActionResult> Login() {}
public async Task<IActionResult> ForgotPassword() {}
}
První metoda přihlašování používá filtr AllowAnonymous (atribut) k přepsání autorizačního filtru nastaveného na úrovni řadiče. Akce ForgotPassword (a jakákoli jiná akce ve třídě, která nemá atribut AllowAnonymous), bude vyžadovat ověřený požadavek.
Filtry se dají použít k odstranění duplicit ve formě běžných zásad zpracování chyb pro rozhraní API. Například Typická zásada rozhraní API je vrátit odpověď NotFound na požadavky odkazující na klíče, které neexistují, a odpověď důvodu chybného požadavku, pokud se ověřování modelu nepovede. Následující příklad znázorňuje tyto dvě zásady v akci:
[HttpPut("{id}")]
public async Task<IActionResult> Put(int id, [FromBody]Author author)
{
if ((await _authorRepository.ListAsync()).All(a => a.Id != id))
{
return NotFound(id);
}
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
author.Id = id;
await _authorRepository.UpdateAsync(author);
return Ok();
}
Nepovolujte, aby vaše metody akcí byly nepotřebné s podmíněným kódem. Místo toho tyto zásady vyžádejte do filtrů, které se dají použít podle potřeby. V tomto příkladu se kontrola ověření modelu, ke kterému by mělo dojít při odeslání příkazu do rozhraní API, může nahradit následující atribut:
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
}
do projektu můžete přidat ValidateModelAttribute jako závislost NuGet zahrnutím balíčku Ardalis. ValidateModel . Pro rozhraní API můžete použít ApiController atribut k vykonání tohoto chování bez nutnosti samostatného ValidateModel filtru.
Podobně lze použít filtr ke kontrole, zda záznam existuje a vrátí 404 před provedením akce, a eliminuje nutnost provádět tyto kontroly v akci. Po vyzkoušení běžných konvencí a jejich uspořádání do samostatného kódu infrastruktury a obchodní logiky z uživatelského rozhraní by vaše metody akce MVC měly být extrémně tenké:
[HttpPut("{id}")]
[ValidateAuthorExists]
public async Task<IActionResult> Put(int id, [FromBody]Author author)
{
await _authorRepository.UpdateAsync(author);
return Ok();
}
další informace o implementaci filtrů a stažení pracovní ukázky najdete v článku o časopise MSDN, reálné ASP.NET Core filtry MVC.
Odkazy – strukturování aplikací
- Místa
https://docs.microsoft.com/aspnet/core/mvc/controllers/areas- MSDN Magazine – řezy funkcí pro ASP.NET Core MVC
https://docs.microsoft.com/archive/msdn-magazine/2016/september/asp-net-core-feature-slices-for-asp-net-core-mvc- Outlook
https://docs.microsoft.com/aspnet/core/mvc/controllers/filters- MSDN Magazine – filtry MVC ASP.NET Core Real World
https://docs.microsoft.com/archive/msdn-magazine/2016/august/asp-net-core-real-world-asp-net-core-mvc-filters
Zabezpečení
Zabezpečení webových aplikací je velké téma s mnoha důležitými informacemi. Ve své základní úrovni zabezpečení zahrnuje jistotu, že víte, komu daný požadavek pochází, a potom zajistěte, aby žádost měla přístup jenom k prostředkům, které by měl mít. Ověřování je proces porovnávání přihlašovacích údajů dodaných s žádostí v důvěryhodném úložišti dat, aby bylo možné zjistit, jestli by se žádost měla považovat za přicházející ze známé entity. Autorizace je proces omezení přístupu k určitým prostředkům na základě identity uživatele. Třetí problém se zabezpečením chrání žádosti před odposloucháváním třetími stranami, pro které byste měli aspoň zajistit, aby vaše aplikace používala SSL.
Identita
ASP.NET Core Identita je systém členství, který můžete použít k podpoře funkcí přihlášení pro vaši aplikaci. Nabízí podporu místních uživatelských účtů a také podporu externího poskytovatele přihlášení od poskytovatelů, jako je například účet Microsoft, Twitter, Facebook, Google a další. kromě ASP.NET Core identity může vaše aplikace používat ověřování systému windows nebo poskytovatele identity jiného výrobce jako Server identit.
ASP.NET Core Identita je obsažena v nových šablonách projektu, pokud je vybrána možnost jednotlivé uživatelské účty. Tato šablona zahrnuje podporu pro registraci, přihlášení, externí přihlášení, zapomenutá hesla a další funkce.

Obrázek 7-3. Vyberte jednotlivé uživatelské účty, pro které má být předem nakonfigurovaná identita.
Podpora identit je nakonfigurována při spuštění, v ConfigureServices i v konfiguraci:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
app.UseIdentity();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Je důležité, aby se UseIdentity zobrazoval před UseMvc v metodě configure. Při konfiguraci identity v ConfigureServices si všimněte volání AddDefaultTokenProviders. To nemá nic dělat s tokeny, které se dají použít k zabezpečení webové komunikace, ale odkazuje na poskytovatele, kteří vytvoří výzvy, které se dají uživatelům poslat přes SMS, nebo e-mailem, aby mohli potvrdit jejich identitu.
můžete si přečíst další informace o konfiguraci dvojúrovňové ověřování a povolení externích poskytovatelů přihlášení z oficiálních ASP.NET Core dokumentů.
Authentication
Ověřování je proces, který určuje, kdo přistupuje k systému. pokud používáte ASP.NET Core Identity a metody konfigurace uvedené v předchozí části, automaticky se v aplikaci nakonfigurují některé výchozí hodnoty ověřování. Můžete však také nakonfigurovat tyto výchozí hodnoty ručně nebo přepsat ty nastavené hodnotou AddIdentity. Pokud používáte identitu, nakonfigurujeme jako výchozí schéma ověřování pomocí souborů cookie.
V rámci ověřování na základě webu je obvykle k dispozici až pět akcí, které mohou být provedeny při ověřování klienta systému. Jsou to:
- Prohlížečů. Použijte informace poskytované klientem k vytvoření identity pro použití v rámci aplikace.
- Výzev. Tato akce se používá k vyžadování klienta k identifikaci.
- Zalomen. Informujte klienta o tom, že je zakázaný provést akci.
- Přihlaste se. Existující klient budete mít nějakým způsobem trvale.
- Odhlásit se. Odeberte klienta z trvalosti.
Pro ověřování ve webových aplikacích existuje mnoho běžných postupů. Tyto jsou označovány jako schémata. Dané schéma definuje akce pro některé nebo všechny výše uvedené možnosti. Některá schémata podporují pouze podmnožinu akcí a mohou vyžadovat samostatné schéma pro jejich provedení. Například schéma OpenId-Connect (OIDC) nepodporuje přihlášení nebo odhlášení, ale obvykle je nakonfigurované tak, aby pro tuto stálost používalo ověřování souborem cookie.
v ASP.NET Core aplikaci můžete nakonfigurovat i DefaultAuthenticateScheme volitelná konkrétní schémata pro každou akci popsanou výše. Například,, DefaultChallengeScheme DefaultForbidScheme atd. Volání AddIdentity<TUser,TRole> nakonfiguruje řadu aspektů aplikace a přidá mnoho požadovaných služeb. Zahrnuje také toto volání ke konfiguraci schématu ověřování:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
});
Tato schémata používají soubory cookie pro trvalost a přesměrování na přihlašovací stránky pro ověřování ve výchozím nastavení. Tato schémata jsou vhodná pro webové aplikace, které komunikují s uživateli přes webové prohlížeče, ale nedoporučují se pro rozhraní API. Místo toho budou rozhraní API obvykle používat jinou formu ověřování, například tokeny nosiče JWT.
Webová rozhraní API jsou spotřebována kódem, například HttpClient v aplikacích .NET a ekvivalentními typy v jiných rozhraních. Tito klienti očekávají použitelnou odpověď z volání rozhraní API nebo stavový kód, který indikuje, co, pokud nějaký problém nastal. Tito klienti nedělají interakci v prohlížeči a nevykreslují ani nekomunikují s jakýmkoli kódem HTML, který může rozhraní API vracet. Proto není vhodné pro koncové body rozhraní API přesměrovat klienty na přihlašovací stránky, pokud nejsou ověřené. Další schéma je vhodnější.
Chcete-li nakonfigurovat ověřování pro rozhraní API, můžete nastavit ověřování jako následující, používané PublicApi projektem v referenční aplikaci eShopOnWeb:
services.AddAuthentication(config =>
{
config.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(config =>
{
config.RequireHttpsMetadata = false;
config.SaveToken = true;
config.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
Přestože je možné nakonfigurovat v jednom projektu více různých schémat ověřování, je mnohem jednodušší nakonfigurovat jedno výchozí schéma. Z tohoto důvodu, mimo jiné, odkazuje referenční aplikace eShopOnWeb své rozhraní API na svůj vlastní projekt, PublicApi a to odděleně od hlavního Web projektu, který obsahuje zobrazení a Razor Pages aplikace.
Ověřování v Blazor aplikacích
Blazorserverové aplikace mohou využívat stejné funkce ověřování jako jakákoli jiná aplikace ASP.NET Core. BlazorWebAssemblyaplikace ale nemůžou používat integrovanou identitu a poskytovatele ověřování, protože se spouštějí v prohlížeči. BlazorWebAssemblyaplikace můžou ukládat stav ověřování uživatelů místně a můžou získat přístup k deklaracím, abyste zjistili, jaké akce by uživatelé měli dělat. Nicméně všechny kontroly ověřování a autorizace by se měly provádět na serveru bez ohledu na logiku implementovanou v rámci Blazor WebAssembly aplikace, protože uživatelé můžou aplikaci snadno obejít a komunikovat přímo s rozhraními API.
Reference – ověřování
- Akce ověřování a výchozí hodnoty
https://stackoverflow.com/a/52493428- Ověřování a autorizace pro spa
https://docs.microsoft.com/aspnet/core/security/authentication/identity-api-authorization- BlazorASP.NET Core Ověřování a autorizace
https://docs.microsoft.com/aspnet/core/blazor/security/- Zabezpečení: Ověřování a autorizace v ASP.NET Web Forms aBlazor
https://docs.microsoft.com/dotnet/architecture/blazor-for-web-forms-developers/security-authentication-authorization
Autorizace
Nejjednodušší forma autorizace zahrnuje omezení přístupu na anonymní uživatele. Této funkce lze dosáhnout použitím atributu [ Authorize ] na určité kontrolery nebo akce. Pokud se používají role, je možné atribut dále rozšířit a omezit přístup na uživatele, kteří patří do určitých rolí, jak je znázorněno níže:
[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
}
V takovém případě budou mít uživatelé, kteří patří do rolí HRManager nebo Finance (nebo obou) přístup k SalaryControlleru. Pokud chcete vyžadovat, aby uživatel patřil do více rolí (nejen jedné z několika), můžete atribut použít vícekrát a pokaždé zadat požadovanou roli.
Určení určitých sad rolí jako řetězců v mnoha různých řadičích a akcích může vést k nežádoucímu opakování. Minimálně definujte konstanty pro tyto řetězcové literály a používejte konstanty kdekoli, kde potřebujete zadat řetězec. Můžete také nakonfigurovat zásady autorizace, které zapouzdřují autorizační pravidla, a pak při použití atributu Authorize zadat zásadu místo [ jednotlivých ] rolí:
[Authorize(Policy = "CanViewPrivateReport")]
public IActionResult ExecutiveSalaryReport()
{
return View();
}
Pomocí zásad tímto způsobem můžete oddělit druhy akcí, které jsou omezené, od konkrétních rolí nebo pravidel, která se na tyto akce vztahují. Pokud později vytvoříte novou roli, která potřebuje mít přístup k určitým prostředkům, stačí aktualizovat zásadu, a ne aktualizovat všechny seznam rolí u každého [ atributu ] Authorize.
Deklarace identit
Deklarace identity jsou páry hodnot názvů, které představují vlastnosti ověřeného uživatele. Můžete například uložit číslo zaměstnance uživatele jako žádost. Deklarace identity je pak možné použít jako součást zásad autorizace. Můžete vytvořit zásadu s názvem EmployeeOnly, která vyžaduje existenci deklarace s názvem EmployeeNumber, jak je znázorněno v tomto příkladu:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthorization(options =>
{
options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
});
}
Tuto zásadu je pak možné použít s atributem Authorize k ochraně jakéhokoli kontroleru nebo [ ] akce, jak je popsáno výše.
Zabezpečení webových rozhraní API
Většina webových rozhraní API by měla implementovat ověřovací systém založený na tokenech. Ověřování pomocí tokenů je bez stavu a je navržené tak, aby bylo škálovatelné. V ověřovacím systému založeném na tokenu se klient musí nejprve ověřit u zprostředkovatele ověřování. V případě úspěchu se klientovi vystaví token, což je jednoduše kryptograficky smysluplný řetězec znaků. Nejběžnějším formátem tokenů je JSON Web Token JWT (často se vyslovuje "jot"). Když pak klient potřebuje vydat požadavek na rozhraní API, přidá tento token jako hlavičku požadavku. Server pak před dokončením požadavku ověří token, který se nachází v hlavičce požadavku. Tento proces znázorňuje obrázek 7–4.

Obrázek 7–4. Ověřování na základě tokenů pro webová rozhraní API.
Můžete vytvořit vlastní ověřovací službu, integrovat se službou Azure AD a OAuth nebo implementovat službu pomocí open source nástroje, jako je IdentityServer.
Tokeny JWT mohou vkládat deklarace identity o uživateli, které je možné číst na klientovi nebo serveru. K zobrazení obsahu tokenu JWT jwt.io nástroj, jako je jwt.io. Do tokenů JTW neukládejte citlivá data, jako jsou hesla nebo klíče, protože jejich obsah je snadno čitelný.
Při použití tokenů JWT s spa nebo aplikacemi musíte token uložit někam do klienta a pak ho přidat do každého volání Blazor WebAssembly rozhraní API. Tato aktivita se obvykle provádí jako hlavička, jak ukazuje následující kód:
// AuthService.cs in BlazorAdmin project of eShopOnWeb
private async Task SetAuthorizationHeader()
{
var token = await GetToken();
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
Po volání výše uvedené metody budou mít požadavky provedené pomocí vložených tokenů do hlaviček požadavku, což umožní rozhraní API na straně serveru požadavek ověřit a _httpClient autorizovat.
Vlastní zabezpečení
Buďte obzvláště opatrní při zavádění vlastní implementace kryptografie, členství uživatelů nebo systému generování tokenů. K dispozici je mnoho komerčních a open source alternativ, které budou mít téměř jistě lepší zabezpečení než vlastní implementace.
Reference – zabezpečení
- Přehled dokumentace k zabezpečení
https://docs.microsoft.com/aspnet/core/security/- Vynucení SSL v ASP.NET Core aplikaci
https://docs.microsoft.com/aspnet/core/security/enforcing-ssl- Úvod do identity
https://docs.microsoft.com/aspnet/core/security/authentication/identity- Úvod do autorizace
https://docs.microsoft.com/aspnet/core/security/authorization/introduction- Ověřování a autorizace pro API Apps v Azure App Service
https://docs.microsoft.com/azure/app-service-api/app-service-api-authentication- Server identit
https://github.com/IdentityServer
Komunikace klienta
Kromě zobrazování stránek a reagování na požadavky na data prostřednictvím webových rozhraní API mohou ASP.NET Core aplikace komunikovat přímo s připojenými klienty. Tato odchozí komunikace může využívat různé technologie přenosu, nejběžnější jsou webSockety. ASP.NET Core SignalR je knihovna, která usnadňuje přidávání komunikačních funkcí mezi klienty v reálném čase do vašich aplikací. SignalR podporuje celou řadu technologií přenosu, včetně webSocketů, a abstrahuje od vývojářů k mnoha podrobnostem implementace.
Komunikace klientů v reálném čase, ať už přímo nebo jinými technikami pomocí protokolu WebSocket, je užitečná v různých scénářích aplikací. Možné příklady:
Aplikace v živé chatovací místnosti
Monitorování aplikací
Aktualizace průběhu úlohy
Oznámení
Interaktivní formulářové aplikace
Při sestavování klientské komunikace do vašich aplikací jsou obvykle dvě komponenty:
Správce připojení na straně serveru (SignalR Hub, WebSocketManager WebSocketHandler)
Knihovna na straně klienta
Klienti nejsou omezeni pouze na prohlížeče – mobilní aplikace, konzolové aplikace a další nativní aplikace mohou komunikovat také pomocí SignalR/WebSocketů. Následující jednoduchý program zobrazí veškerý obsah odeslaný do chatovací aplikace do konzoly jako součást ukázkové aplikace WebSocketManager:
public class Program
{
private static Connection _connection;
public static void Main(string[] args)
{
StartConnectionAsync();
_connection.On("receiveMessage", (arguments) =>
{
Console.WriteLine($"{arguments[0]} said: {arguments[1]}");
});
Console.ReadLine();
StopConnectionAsync();
}
public static async Task StartConnectionAsync()
{
_connection = new Connection();
await _connection.StartConnectionAsync("ws://localhost:65110/chat");
}
public static async Task StopConnectionAsync()
{
await _connection.StopConnectionAsync();
}
}
Zvažte způsoby, jakými vaše aplikace komunikují přímo s klientskými aplikacemi, a zvažte, jestli by komunikace v reálném čase vylepšuje uživatelské prostředí vaší aplikace.
Reference – komunikace klienta
- ASP.NET Core SignalR
https://github.com/dotnet/aspnetcore/tree/main/src/SignalR- WebSocket Manager
https://github.com/radu-matei/websocket-manager
Návrh řízený doménou – Měli byste ho použít?
Domain-Driven Design (DDD) je agilní přístup k vytváření softwaru, který klade důraz na zaměření na obchodní doménu. Klade velký důraz na komunikaci a interakci s odborníky na obchodní doménu, kteří mohou s vývojáři souviset s tím, jak funguje skutečný systém. Pokud například používáte systém, který zpracovává obchody s akciemi, může být váš odborník na doménu zkušeným zprostředkovatelem akcií. Ddd je navržený tak, aby řešoval velké složité obchodní problémy, a často není vhodný pro menší a jednodušší aplikace, protože investice do porozumění a modelování domény za to stojí.
Při vytváření softwaru s přístupem DDD by váš tým (včetně netechnických účastníků a přispěvatelů) měl vyvinout všudypřítomný jazyk pro problémový prostor. To znamená, že stejná terminologie by se měla používat pro modelovaný koncept z reálného světa, ekvivalent softwaru a jakékoli struktury, které by mohly existovat pro zachování konceptu (například databázových tabulek). Proto by koncepty popsané v všudypřítomných jazycích měly být základem doménového modelu.
Doménový model se skládá z objektů, které vzájemně komunikují, aby představovaly chování systému. Tyto objekty mohou spadat do následujících kategorií:
Entity ,které představují objekty s vláknem identity. Entity se obvykle ukládají v trvalosti s klíčem, pomocí kterého je lze později načíst.
Agregace, které představují skupiny objektů, které by měly být zachovány jako jednotka.
Objekty hodnotpředstavující koncepty, které lze porovnat na základě součtu hodnot jejich vlastností. Například DateRange skládající se z počátečního a koncového data.
Události domény, které představují věci, ke kterým v systému dochází a které jsou zajímavé pro jiné části systému.
Doménový model DDD by měl zapouzdřit složité chování v rámci modelu. Entity by zejména neměly být pouze kolekcemi vlastností. Pokud doménový model nemá chování a pouze reprezentuje stav systému, je to anemický model, který je v DDD nežádoucí.
Kromě těchto typů modelů používá DDD obvykle různé vzory:
Úložiště– pro abstrakci podrobností o trvalosti.
Objekt provytváření objektů pro zapouzdření vytváření složitých objektů.
Službypro zapouzdření komplexního chování nebo podrobnosti implementace infrastruktury.
Příkazpro oddělení vydávajících příkazů a spuštění samotného příkazu.
Specifikacepro zapouzdření podrobností dotazu.
DDD také doporučuje použití dříve popsané čisté architektury, což umožňuje volné párování, zapouzdření a kód, které lze snadno ověřit pomocí testů jednotek.
Kdy byste měli použít DDD
DDD je vhodné pro velké aplikace s významnou obchodní (nejen technickou) složitostí. Aplikace by měla vyžadovat znalosti expertů domény. V samotném modelu domény by mělo být významné chování, které představuje obchodní pravidla a interakce, a to nad rámec pouhého ukládání a načítání aktuálního stavu různých záznamů z úložišť dat.
Pokud byste neměli použít DDD
DDD zahrnuje investice do modelování, architektury a komunikace, které nemusí být oprávněné pro menší aplikace nebo aplikace, které jsou v podstatě pouze CRUD (vytváření, čtení, aktualizace a odstranění). Pokud se rozhodnete získat přístup k aplikaci po DDD, ale zjistíte, že vaše doména má model anemic bez chování, možná budete muset vzít v úvahu svůj přístup. Buď vaše aplikace nemusí potřebovat DDD, nebo můžete potřebovat pomoc při refaktoringu vaší aplikace k zapouzdření obchodní logiky v doménovém modelu, nikoli v databázi nebo uživatelském rozhraní.
Hybridní přístup by byl pro transakční nebo složitější oblasti aplikace použit pouze DDD, ale ne pro jednodušší části CRUD nebo jen pro čtení. Například nemusíte mít omezení agregace, pokud se dotazuje na data, abyste zobrazili sestavu nebo aby bylo možné vizualizovat data pro řídicí panel. Je naprosto přijatelné, abyste měli samostatný, jednodušší model pro čtení těchto požadavků.
Odkazy – Domain-Driven návrh
- DDD v jednoduché angličtině (odpověď StackOverflow)
https://stackoverflow.com/questions/1222392/can-someone-explain-domain-driven-design-ddd-in-plain-english-please/1222488#1222488
Nasazení
proces nasazení ASP.NET Core aplikace se účastní několika kroků bez ohledu na to, kde se bude hostovat. Prvním krokem je publikování aplikace, která se dá provést pomocí dotnet publish příkazu CLI. Tento krok zkompiluje aplikaci a umístí všechny soubory potřebné ke spuštění aplikace do určené složky. když nasazujete z Visual Studio, tento krok se provádí automaticky. Složka Publish obsahuje .exe a .dll soubory pro aplikaci a její závislosti. Samostatně obsažená aplikace bude obsahovat také verzi modulu runtime .NET. ASP.NET Core aplikace budou zahrnovat také konfigurační soubory, statické prostředky klienta a zobrazení MVC.
ASP.NET Core aplikace jsou konzolové aplikace, které musí být spuštěny, když se server spustí a restartuje, pokud dojde k chybě aplikace (nebo serveru). K automatizaci tohoto procesu lze použít správce procesů. nejběžnějšími správci procesů pro ASP.NET Core jsou Nginx a Apache v systémech Linux a IIS nebo služba Windows na Windows.
kromě správce procesů mohou ASP.NET Core aplikace používat reverzní proxy server. Zpětný proxy server přijímá požadavky HTTP z Internetu a předá je Kestrel po předběžném zpracování. Reverzní proxy servery poskytují vrstvu zabezpečení pro aplikaci. Kestrel také nepodporuje hostování více aplikací na stejném portu, takže techniky, jako jsou hlavičky hostitelů, nelze s ní používat, aby bylo možné hostovat více aplikací na stejném portu a IP adrese.

Obrázek 7-5. ASP.NET hostované v Kestrel za reverzním proxy server
Dalším scénářem, ve kterém může mít reverzní proxy být užitečný, je zabezpečení více aplikací pomocí protokolu SSL/HTTPS. V takovém případě musí mít nakonfigurován protokol SSL pouze reverzní proxy server. Komunikace mezi zpětným proxy server a Kestrel může probíhat přes protokol HTTP, jak je znázorněno na obrázku 7-6.

Obrázek 7-6. ASP.NET hostovaný za reverzním proxy server zabezpečeným protokolem HTTPS
stále oblíbeným přístupem je hostování aplikace ASP.NET Core v kontejneru docker, který pak můžete hostovat místně nebo nasadit do Azure pro cloudové hostování. Kontejner Docker může obsahovat kód vaší aplikace spuštěný v Kestrel a bude nasazen za reverzním proxy server, jak je uvedeno výše.
pokud jste hostitelem aplikace v Azure, můžete použít Microsoft Azure Application Gateway jako vyhrazené virtuální zařízení k poskytnutí několika služeb. Kromě toho, že funguje jako reverzní proxy server pro jednotlivé aplikace, Application Gateway může také nabízet tyto funkce:
Vyrovnávání zatížení HTTP
Přesměrování zpracování SSL (jenom SSL pro Internet)
Koncové šifrování protokolu SSL
Směrování na více webů (konsolidovat až 20 lokalit na jednom Application Gateway)
Firewall webových aplikací
Podpora protokolu WebSocket
Pokročilá diagnostika
Další informace o možnostech nasazení Azure najdete v kapitole 10.
Odkazy – nasazení
- Přehled hostování a nasazení
https://docs.microsoft.com/aspnet/core/publishing/- Kdy použít Kestrel s reverzním proxy serverem
https://docs.microsoft.com/aspnet/core/fundamentals/servers/kestrel#when-to-use-kestrel-with-a-reverse-proxy- hostování ASP.NET Core aplikací v docker
https://docs.microsoft.com/aspnet/core/publishing/docker- Představujeme Azure Application Gateway
https://docs.microsoft.com/azure/application-gateway/application-gateway-introduction