ASP NET Core MVC 6 Ing Janouek Star

  • Slides: 27
Download presentation
ASP. NET Core (MVC 6) Ing. Janoušek

ASP. NET Core (MVC 6) Ing. Janoušek

Stará architektura ASP. NET před „Core“ HTTP Modules Web Forms MVC HTTP Handlers Request

Stará architektura ASP. NET před „Core“ HTTP Modules Web Forms MVC HTTP Handlers Request Pipeline Web API Caching . NET Framework IIS OS (Windows) Session State System. Web ASP. NET

Nová architektura ASP. NET Core ASP. NET Web API MVC Web Pages Middleware. NET

Nová architektura ASP. NET Core ASP. NET Web API MVC Web Pages Middleware. NET Core CLR . NET CLR IIS Self-hosted OS

Základní ASP. NET Core aplikace // Startup. cs // Program. cs public class Startup

Základní ASP. NET Core aplikace // Startup. cs // Program. cs public class Startup public class Program { { public void Configure(IApplication. Builder app) public static void Main(string[] args) { { app. Run(context => Build. Web. Host(args). Run(); { } return context. Response. Write. Async("Hello from ASP. NET Core!"); public static IWeb. Host Build. Web. Host(string[] args) { }); Web. Host. Create. Default. Builder(args) } . Use. Startup<Startup>() } . Build(); } }

project. json (project. [environment]. json ) • Náhrada za web. config { // Startup.

project. json (project. [environment]. json ) • Náhrada za web. config { // Startup. cs "Logging": { "Include. Scopes": false, public class Startup { "Log. Level": { public Startup(IConfiguration configuration) "Default": "Warning" { } string db. Connection. String = configuration["my. Data: Connection. String"]; }, } "cors": { "rules": [ … { "origin": "https: //manage. iis. net", "allow": true } ] }, "my. Data": { "Connection. String": "Server=tcp: ……………", "Fb. Id": "123456789" } } }

Základní vlastnosti ASP. NET Core • Není potřeba IIS server. • Kestrel – jednoduchý,

Základní vlastnosti ASP. NET Core • Není potřeba IIS server. • Kestrel – jednoduchý, multiplatformní webový server (preferovaný server) • Konfigurace aplikace pomocí JSON. • Nejde o monolit jako v předchozích verzích. Aplikaci si složíte z jednotlivých komponent (Nu. Get balíčky): https: //www. nuget. org/packages/Microsoft. Asp. Net. Core/2. 0. 1 Tato vlastnost umožňuje nezávislejší a rychlejší vývoj (je možné vydat novou verzi pouze určitého balíčku, bez nutnosti aktualizace celé platformy).

Middleware Application Middleware Server Host Request Response

Middleware Application Middleware Server Host Request Response

Middleware • Nahrazuje HTTP moduly, handlery, atd… - existovalo v MVC 5 // Startup.

Middleware • Nahrazuje HTTP moduly, handlery, atd… - existovalo v MVC 5 // Startup. cs public void Configure(IApplication. Builder app, IHosting. Environment env, ILogger. Factory loggerfactory) { app. Use. Error. Handler("/Home/Error"); app. Use. Static. Files(); app. Use. Session(); app. Use. Identity(); app. Use. Middleware<My. Custom. Middleware>(); app. Use. Mvc(routes => { routes. Map. Route( name: "default", template: "{controller=Home}/{action=Index}/{id? }"); }

Middleware, které jsou základní součástí • Autentizace • CORS (Cross-Origin Resource Sharing) • Routing

Middleware, které jsou základní součástí • Autentizace • CORS (Cross-Origin Resource Sharing) • Routing • Session • Statické soubory • Další je možné získat jako Nu. Get-y - včetně MVC (6)

Vlastní middleware • Jakákoliv třída, která má: • Konstruktor očekávající parametr typu Request. Delegate

Vlastní middleware • Jakákoliv třída, která má: • Konstruktor očekávající parametr typu Request. Delegate (může být více parametrů, které budou získány prostřednictvím DI). • Metodu Invoke viz. níže. • Další middleware v pořadí je volán pomocí Request. Delegate získaného v konstruktoru. public class My. Custom. Middleware { private readonly Request. Delegate next; public My. Custom. Middleware(Request. Delegate next) { this. next = next; } public async Task Invoke(Http. Context context) { await context. Response. Write. Async("Můj první middleware"); await this. next. Invoke(context); } }

Dependency Injection • Vstřikování/předávání závislostí. • ASP. NET (i MVC 6) jej plně podporují

Dependency Injection • Vstřikování/předávání závislostí. • ASP. NET (i MVC 6) jej plně podporují v základu. Závislosti je možné předat do v podstatě kamkoliv (toto byl problém v předchozích verzích MVC). • Slouží mimo jiné ke konfiguraci jednotlivých middleware. Definují se v rámci Startup. cs • Závislosti se označují jako „služby“ (využívá se návrhového vzoru Service Locator). • Typy služeb: • • Instance – celou dobu se používá instance, kterou definujete. Transient – při každém požadavku na službu vznikne nová instance. Singleton – instance je vytvořena jen jednou pro celou aplikaci. Scoped – instance je vytvořena jen jednou pro aktuální požadavek.

Dependency Injection // Startup. cs // nějaký controller public void Configure. Services(IService. Collection services)

Dependency Injection // Startup. cs // nějaký controller public void Configure. Services(IService. Collection services) public class App. Controller : Controller { { private ISms. Sender sms. Sender; services. Add. Identity<Application. User, User. Role. Entity>() services. Add. User. Store<User. Store>(); public App. Controller(ISms. Sender sms. Sender){ services. Add. Role. Store<Role. Store>(); this. sms. Sender = sms. Sender; services. Add. User. Manager<Application. User. Manager>() } services. Configure<Identity. Options>(options => public IAction. Result Some. Action() { { options. Password. Require. Digit = true; this. sms. Sender. Send("+420721. . . ", "text SMS"); . . . . }); IEmail. Sender email. Sender = this services. Add. Singleton<ISms. Sender, Sms. Sender. Service>(); . Http. Context services. Add. Singleton<IEmail. Sender, Email. Sender. Service>(); . Request. Services services. Add. Scoped<Authorization. Service>(); . Get. Service(typeof(IEmail. Sender)); email. Sender. Send("email@email. cz", "text"); services. Add. Session(); return View(); } services. Add. Mvc(); } }

MVC 6

MVC 6

ASP. NET MVC < 5

ASP. NET MVC < 5

ASP. NET Core & MVC 6 MVC + Web API + Web Pages =

ASP. NET Core & MVC 6 MVC + Web API + Web Pages = ASP. NET MVC 6

MVC - obecně • Model – business logika – například přístup k DB, atd…

MVC - obecně • Model – business logika – například přístup k DB, atd… - obecně „data“ • View – prezentační část – jak se mají data zobrazit • Controller – zpracovává interakce od uživatele, pracuje s modelem a stará se o výběr šablony. • Router – není přímo součástí MVC (jako návrhového vzoru). Stará se o mapování URL.

Controller • Třída, která dědí z abstraktní třídy „Controller“. • Musí být v adresáři

Controller • Třída, která dědí z abstraktní třídy „Controller“. • Musí být v adresáři „Controllers“ • Název třídy musí mít sufix „Controller“. Například „Product. Controller“. • Každý controller obsahuje „akce“ – metody s návratovým typem „IAction. Result“ (interface). • Vše musí být public class Product. Controller : Controller { public IAction. Result Detail(string id) { return View(); } public IAction. Result List() { return View(); } public IAction. Result Json() { new Json. Result(new { Name = "Auto" }); } }

Model • Libovolná třída – co bude modelem závisí pouze na vás… • Data

Model • Libovolná třída – co bude modelem závisí pouze na vás… • Data od klienta (v podobě modelu) lze automaticky validovat, pomocí speciálních atributů. • Model se předává do View jako parametr metody „View(…. ); “ public class Login. Customer. Form { [Required] [Email. Address] [Display(Name = "Email")] public string Email { get; set; } [Required] [Data. Type(Data. Type. Password)] [Display(Name = "Heslo")] public string Password { get; set; } [Display(Name = "Trvalé přihlášení")] public bool Remember. Me { get; set; } }

View • Soubory s příponou „. cshtml“ • Využívají šablonovací engine/jazyk: „Razor“ • Obsahují

View • Soubory s příponou „. cshtml“ • Využívají šablonovací engine/jazyk: „Razor“ • Obsahují standardní HTML + v případě potřeby Razor kód. • Musí být v adresáři „Views“. • Šabloka k akci v controlleru musí být v souboru: „Views/{Název. Controlleru}/{Název. Akce}. cshtml“ Toto chování lze změnit (lze definovat šablonu ručně). • Data z contolleru se předávají jako „Model“, nebo přes „View. Bag“.

@model Booking. Login. User. Form // _Account. Layout. cshtml @{ Layout = "_Account. Layout";

@model Booking. Login. User. Form // _Account. Layout. cshtml @{ Layout = "_Account. Layout"; <!DOCTYPE html> View. Data["Title"] = "Přihlášení"; <html lang="cs"> <head> } <meta charset="utf-8"> <title>@View. Data["Title"]</title> @using (Html. Begin. Form("Login", "Account", Form. Method. Post)) </head> { <body> @Html. Validation. Summary(true); @Render. Body() <div> </body> @Html. Label. For(model => model. Email) @Html. Text. Box. For(model => model. Email) </html> @Html. Validation. Message. For(model => model. Email) </div> <div> @Html. Label. For(model => model. Password) @Html. Password. For(model => model. Password) @{ @Html. Validation. Message. For(model => model. Password) Layout = "_Another. Layout"; </div> <div> View. Data["Title"] = "Ukázka"; } @Html. Label. For(model => model. Remember. Me) @Html. Check. Box. For(model => model. Remember. Me) </div> <ul> @foreach(string name in View. Bag["Name. List"]){ <li>@name</li> <button type="submit">Přihlásit se</button> } } </ul> @Html. Action. Link("Text odkazu", "Nazev. Akce", "Nazev. Controlleru")

@model Booking. Login. User. Form @{ Layout = "_Account. Layout"; View. Data["Title"] = "Přihlášení";

@model Booking. Login. User. Form @{ Layout = "_Account. Layout"; View. Data["Title"] = "Přihlášení"; } <form asp-controller="Account" asp-action="Login" method="post"> <div asp-validation-summary="All"></div> <label asp-for="Email"></label> <input asp-for="Email" /> <span asp-validation-for="Email"></span> </div> <label asp-for="Password"></label> <input asp-for="Password" /> <span asp-validation-for="Password"></span> </div> <input asp-for="Remember. Me" /> <label asp-for="Remember. Me"></label> </div> <button type="submit">Přihlásit se</button> </form>

Model binding • Mapování vstupních dat (od uživatele) na objekt/parametr akce. // V contolleru

Model binding • Mapování vstupních dat (od uživatele) na objekt/parametr akce. // V contolleru public IAction. Result Login(Login. Customer. Form model, string return. Url = null) { if(Model. State. Is. Valid) { // model je validní // přidání vlastní chyby if(model. Email. Index. If("vsb. cz") == -1){ Model. State. Add. Model. Error("Email", "Email musí obsahovat ""vsb. cz""); } } return View(model); }

Routing • Stará se o mapování URL na „kód“ – co se má vykonat,

Routing • Stará se o mapování URL na „kód“ – co se má vykonat, když zadám určitou URL. // Startup. cs public void Configure(IApplication. Builder app) { app. Use. Mvc(routes => { // Stránka konkrétního subjektu routes. Map. Route(name: "admin. Route", template: "admin/{lang}/{controller}/{action}/{id? }", defaults: new { lang = "cs", area = "subject", controller = "Home", action = "Index" }, constraints: new { lang = "[a-z]{2}" } ); routes. Map. Route( name: "default", template: "{controller}/{action}/{id? }", defaults: new { controller = "Home", action = "Index" } ); }

Autorizace [Authorize(Roles = "Administrator")] public class Administration. Controller : Controller { } • Autorizace

Autorizace [Authorize(Roles = "Administrator")] public class Administration. Controller : Controller { } • Autorizace založená na rolích – stejně jako u Web. Forms. • Autorizace založená na „Policy“. • Policy mohou obsahovat jakoukoliv vlastní logiku. • Policy můžou obsahovat: • Role • Claims („tvrzení“? ) • Požadavky (vlastní logika) [Authorize(Policy = "My. Policy. Name")] public class Administration. Controller : Controller { } // Startup. cs – uvnitř funkce „Configure. Services“ services. Configure<Authorization. Options>(options => { options. Add. Policy("Some. Policy. Name", policy => policy. . . . )); options. Add. Policy( "My. Policy. Name", policy => policy. Requirements. Add(new Admin. Requirement()) ); });

Vlastní policy (Requirement) public class Admin. Requirement : IAuthorization. Handler, IAuthorization. Requirement { public

Vlastní policy (Requirement) public class Admin. Requirement : IAuthorization. Handler, IAuthorization. Requirement { public async Task Handle. Async(Authorization. Handler. Context context) { if (!context. User. Identity. Is. Authenticated) { context. Fail(); return; } Http. Context http. Context = (context. Resource as Microsoft. Asp. Net. Core. Mvc. Filters. Authorization. Filter. Context). Http. Context; My. Service. Name my. Service = (My. Service. Name)http. Context. Request. Services. Get. Service(typeof(My. Service. Name)); if (!my. Service. Check. User(context. User. Identity)) { context. Fail(); return; } context. Succeed(this); } }

Různé • Client side validace – je přímo podporována přes „j. Query Unobtrusive Validation“

Různé • Client side validace – je přímo podporována přes „j. Query Unobtrusive Validation“ • Razor lze používat i mimo MVC (není na něm závislý) • Razor syntaxe: https: //docs. microsoft. com/enus/aspnet/core/mvc/views/razor • Vše je Open-source- https: //github. com/aspnet • Nikdo vás nenutí používat vše. ASP. NET Core je rozdělen na komponenty, které jsou nezávisle. • ASP. NET Core toho umí mnohem více….

Dokumentace ASP. NET https: //docs. asp. net/en/latest/index. html

Dokumentace ASP. NET https: //docs. asp. net/en/latest/index. html