Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00023 005329 19042172 na godz. na dobę w sumie
ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera - książka
ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera - książka
Autor: Liczba stron: 472
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-283-4643-7 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> .net - programowanie
Porównaj ceny (książka, ebook (-35%), audiobook).

Framework ASP.NET Core odzwierciedla zmianę podejścia do technologii strony klienta: niezależność od platformy sprzętowej, łatwiejsze prowadzenie testów jednostkowych i rozbudowa tworzonych systemów. Kolejna wersja frameworka odzwierciedla dalszą ewolucję koncepcji: od aplikacji, które miały być reaktywne i responsywne, do progresywnej realizacji zadań. Również technologia strony serwera poczyniła postępy w zakresie stabilności i wydajności pracy, co w widoczny sposób przyczyniło się do radykalnych zmian kolejnych wersji Angulara. Poprzednie wersje ASP.NET Core i Angulara były znakomitą propozycją dla projektantów całościowych rozwiązań. Czy bezproblemowe stosowanie obu tych narzędzi będzie możliwe w przypadku ich najnowszych wersji?

Dzięki tej książce dowiesz się, w jaki sposób zrealizować kompleksowy projekt aplikacji internetowej, zapewniając efektywną pracę jej części klienckiej i serwerowej za pomocą frameworków ASP.NET Core 2 i Angular 5. Dowiesz się, jak zapewnić obsługę wywołań API oraz routingu po stronie serwera, czym jest dowiązanie dwukierunkowe, jak wykorzystać obiekty Observable i jak wstrzykiwać zależności. Nauczysz się stosować framework Entity Framework Core do tworzenia modelu danych, a framework Bootstrap i narzędzie LESS do nadania odpowiednich stylów. Poznasz różne techniki uwierzytelniania klientów, w tym protokół OAuth 2. Dowiesz się też, jak poprawnie skonfigurować mechanizm odwrotnego pośrednika miedzy serwerami IIS i Kestrel.

W tej książce między innymi:

Nowoczesne aplikacje: oszałamiająca wydajność, wszechobecna prostota!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: ASP.NET Core 2 and Angular 5: Full-Stack Web Development with .NET Core and Angular Tłumaczenie: Rafał Jońca ISBN: 978-83-283-4643-7 Copyright © Packt Publishing 2017. First published in the English language under the title ‘ASP.NET Core 2 and Angular 5 – (9781788293600)’ Polish edition copyright © 2018 by Helion SA All rights reserved. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz HELION SA dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. HELION SA ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Pliki z przykładami omawianymi w książce można znaleźć pod adresem: ftp://ftp.helion.pl/przyklady/asp2an.zip Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/asp2an Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis tre(cid:258)ci O autorze O redaktorach merytorycznych Wst(cid:218)p Rozdzia(cid:239) 1. Przygotowanie (cid:258)rodowiska Dwóch graczy, jeden cel Rewolucja ASP.NET Co nowego w Angularze? Podej(cid:258)cie od pocz(cid:200)tku do ko(cid:241)ca Aplikacja typu SPA Typowe funkcjonalno(cid:258)ci nowoczesnych aplikacji SPA Oczekiwania w(cid:239)a(cid:258)ciciela produktu Projekt przyk(cid:239)adowej aplikacji SPA Wizja To nie b(cid:218)dzie typowa aplikacja „Witaj, (cid:258)wiecie” Aplikacja TestMakerFree Podstawowe funkcjonalno(cid:258)ci i wymagania Przygotowanie (cid:258)rodowiska pracy Uwaga — pomy(cid:258)l, zanim to zrobisz Mit niedzia(cid:239)aj(cid:200)cego kodu Pozosta(cid:241) otwarty na nowo(cid:258)ci, ale wprowadzaj je odpowiedzialnie Wersje narz(cid:218)dzi i bibliotek Konfiguracja projektu Alternatywna konfiguracja z wykorzystaniem wiersza polece(cid:241) Test konfiguracji (cid:258)rodowiska 13 15 19 25 26 26 27 28 29 29 30 32 33 33 33 34 35 36 36 37 38 38 42 42 Poleć książkęKup książkę Spis tre(cid:286)ci Poznawanie projektu Pliki konfiguracyjne Plik Program.cs Plik Startup.cs Plik appsettings.json Plik package.json Plik tsconfig.json Pliki konfiguracyjne narz(cid:218)dzia Webpack Kod po stronie serwerowej Plik Controllers/HomeController.cs Plik Controllers/SampleDataController.cs Folder /Views/ Kod po stronie klienckiej Folder /ClientApp/app/ Przygotowanie projektu Pami(cid:218)(cid:202) podr(cid:218)czna i pliki statyczne Mechanizm stosowany w przesz(cid:239)o(cid:258)ci Powrót do przysz(cid:239)o(cid:258)ci Czas na test Czyszczenie aplikacji klienckiej Ograniczenie liczby komponentów Klasy AppModule Aktualizacja NavMenu Odno(cid:258)niki Poruszana tematyka Podsumowanie Rozdzia(cid:239) 2. Cz(cid:218)(cid:258)(cid:202) serwerowa wykorzystuj(cid:200)ca .NET Core Przep(cid:239)yw danych Zadania modelu widoku Pierwszy model widoku Klasa QuizViewModel Klasa QuizController Dodatkowe metody akcji Sprawdzenie, czy wszystko dzia(cid:239)a Dodawanie pozosta(cid:239)ych kontrolerów Klasa QuestionViewModel Klasa QuestionController Klasa AnswerViewModel Klasa AnswerController Klasa ResultViewModel Klasa ResultController Dzia(cid:239)anie routingu Definiowanie routingu Routing dawniej i dzi(cid:258) Obs(cid:239)uga routingu w .NET Core 4 44 45 45 47 50 51 54 56 61 61 61 62 63 64 66 66 67 67 70 71 72 74 75 76 77 77 79 79 82 82 83 84 86 88 89 89 90 91 92 93 94 96 96 96 98 Poleć książkęKup książkę Dodawanie nowych (cid:258)cie(cid:285)ek Atrapa dostawcy danych Obs(cid:239)uga pojedynczych elementów Poruszana tematyka Podsumowanie Rozdzia(cid:239) 3. Cz(cid:218)(cid:258)(cid:202) kliencka korzystaj(cid:200)ca z frameworka Angular Wzorzec nawigacji Powi(cid:200)zanie ogó(cid:239)-szczegó(cid:239)y Kliencka cz(cid:218)(cid:258)(cid:202) interfejsu dotycz(cid:200)cego quizu Komponent QuizListComponent Nowa klasa HttpClient Metoda onSelect() Plik szablonu Plik arkusza stylów Dodanie komponentu Test Klasa QuizComponent Dodanie plików komponentu Dodanie komponentu Test Do(cid:239)(cid:200)czanie dodatkowych list Wiele instancji jednego komponentu Testowanie i debugowanie Interfejs OnInit i zdarzenia cyklu (cid:285)ycia Implementacja metody ngOnInit Testowanie poprawionej wersji Dwukierunkowe dowi(cid:200)zanie danych Wy(cid:239)(cid:200)czenie dwukierunkowego dowi(cid:200)zania danych Routing po stronie klienckiej Strategie PathLocationStrategy i HashLocationStrategy Refaktoryzacja aplikacji Rejestracja nowej (cid:258)cie(cid:285)ki Aktualizacja komponentu QuizComponent Aktualizacja komponentu QuizListComponent Test routingu Dodanie nowych komponentów Komponent AboutComponent Komponent LoginComponent Komponent PageNotFoundComponent Aktualizacja klasy AppModule Test ca(cid:239)ej aplikacji Poruszana tematyka Podsumowanie Spis tre(cid:286)ci 99 103 103 107 107 109 110 111 111 112 114 117 117 118 118 120 121 121 122 123 124 125 128 129 131 133 133 134 135 136 136 138 139 142 143 143 144 145 145 146 148 151 151 5 Poleć książkęKup książkę Spis tre(cid:286)ci Rozdzia(cid:239) 4. Model danych wykorzystuj(cid:200)cy Entity Framework Core Przygotowania Instalacja Entity Framework Core Podej(cid:258)cia do modelowania danych Najpierw model Najpierw baza danych Najpierw kod Podj(cid:218)cie decyzji Tworzenie encji Klasa ApplicationUser Klasa Quiz Klasa Question Klasa Answer Klasa Result Definiowanie relacji Wzorzec leniwego wczytywania danych w relacjach jeden-do-wielu Konfiguracja obiektu DbContext Strategie inicjalizacji bazy danych Wybór bazy danych Aktualizacja pliku appsettings.json Tworzenie bazy danych Aktualizacja pliku Startup.cs Dodanie migracji pocz(cid:200)tkowej B(cid:239)(cid:200)d braku pliku Dzia(cid:239)anie mechanizmu migracji Implementacja wype(cid:239)niania bazy danymi Utworzenie klasy DbSeeder U(cid:285)ycie DbSeeder w Startup.cs Wype(cid:239)nienie bazy danymi pocz(cid:200)tkowymi Aktualizacja klasy QuizController Narz(cid:218)dzie Mapster Instalacja Podstawy u(cid:285)ycia Aktualizacja klasy Testowanie dostawcy danych Poruszana tematyka Podsumowanie Rozdzia(cid:239) 5. Interakcje po stronie klienckiej Dodawanie, aktualizacja i usuwanie quizów Aktualizacja klasy QuizController Dostosowanie cz(cid:218)(cid:258)ci klienckiej Dodanie komponentu QuizEditController Aktywacja trybu edycji Implementacja funkcjonalno(cid:258)ci usuwania Pierwszy test powa(cid:285)nej interakcji klienta z serwerem Przep(cid:239)yw komunikacji mi(cid:218)dzy klientem i serwerem 6 153 154 154 156 156 157 158 159 160 160 161 164 165 166 168 170 170 172 172 173 174 174 174 176 177 177 178 184 186 186 187 187 187 188 191 192 192 195 195 196 200 200 204 206 207 211 Poleć książkęKup książkę Pytania, odpowiedzi i wyniki Zadania po stronie serwerowej Klasa QuestionController Klasa AnswerController Klasa ResultController Klasa BaseApiController Zadania po stronie klienckiej Dodanie interfejsów Komponent QuestionListComponent Komponent QuestionEditComponent Komponent AnswerListComponent Komponent AnswerEditComponent Komponent ResultListComponent Komponent ResultEditComponent Pe(cid:239)nowymiarowy test aplikacji Poruszana tematyka Podsumowanie Rozdzia(cid:239) 6. Arkusze stylów i uk(cid:239)ad interfejsu graficznego Czy jest a(cid:285) tak (cid:283)le? Wprowadzenie do LESS J(cid:218)zyki arkuszy stylów CSS Przyk(cid:239)adowy kod CSS Czym jest LESS i dlaczego warto go u(cid:285)ywa(cid:202)? Zmienne Dyrektywy importu Zagnie(cid:285)d(cid:285)anie selektorów Domieszki (mixin) Pseudoklasa :extend Dokumentacja LESS Sass, Stylus i inne mo(cid:285)liwo(cid:258)ci Implementacja LESS Instalacja kompilatora LESS Kompilacja plików LESS za pomoc(cid:200) narz(cid:218)dzia Webpack Samodzielne definiowanie stylów kontra u(cid:285)ycie frameworka CSS Podej(cid:258)cie „zróbmy wszystko sami” Zalety Wady Podej(cid:258)cie wykorzystuj(cid:200)ce framework CSS Zalety Wady Wnioski Praca z Bootstrapem Zmiana motywu Przebudowanie plików dystrybucyjnych zewn(cid:218)trznych dostawców Sprawdzenie nowego motywu Spis tre(cid:286)ci 212 213 213 217 221 225 228 228 228 234 237 240 241 243 245 249 250 251 251 252 252 253 253 254 255 256 256 257 258 259 260 260 261 263 264 265 265 265 265 266 266 266 267 267 268 270 7 Poleć książkęKup książkę Spis tre(cid:286)ci Zmiana struktury interfejsu u(cid:285)ytkownika Komponent AppComponent Komponent NavMenuComponent Komponent QuizSearchComponent Plik SVG z logo Szybki test Stylowanie komponentów Enkapsulacja CSS Komponent HomeComponent Komponent QuizListComponent Komponent QuizComponent Komponent QuizEditComponent Komponenty pytania, odpowiedzi i wyniku Ca(cid:239)o(cid:258)ciowy test zmian interfejsu Poruszana tematyka Podsumowanie Rozdzia(cid:239) 7. Formularze i weryfikacja danych Walidacja danych Formularze we frameworku Angular Formularze sterowane szablonami Formularze sterowane modelem Pierwszy reaktywny formularz Dodanie referencji do ReactiveFormsModule Uaktualnienie komponentu QuizEditComponent Dodanie walidatorów Uaktualnienie komponentów Komponent QuestionEditComponent Komponent AnswerEditComponent Komponent ResultEditComponent Debugowanie i testowanie Jak wygl(cid:200)da model formularza? Operator potoku Reagowanie na zmiany Obserwowanie obiektu Observable Rozbudowa dziennika aktywno(cid:258)ci Debugowanie po stronie klienta Testy jednostkowe formularzy Poruszana tematyka Podsumowanie Rozdzia(cid:239) 8. Uwierzytelnianie i autoryzacja Uwierzytelnia(cid:202) czy tego nie robi(cid:202)? Uwierzytelnianie Uwierzytelnianie przy udziale strony trzeciej 8 271 271 273 275 277 277 278 278 282 283 289 294 295 298 299 299 301 302 302 302 304 307 307 308 312 315 315 316 319 321 321 322 323 323 326 326 327 328 328 329 330 330 331 Poleć książkęKup książkę Autoryzacja Autoryzacja przy udziale strony trzeciej Rozwi(cid:200)zania w(cid:239)asne czy firm trzecich? Mechanizmy uwierzytelniania wbudowane w .NET Core Konfiguracja .NET Core Identity Konfiguracja us(cid:239)ugi Identity Klasa ApplicationUser jako klasa potomna Uaktualnienie klasy DbContext Modyfikacja klasy DbSeeder Aktualizacja bazy danych Dodanie migracji dotycz(cid:200)cej us(cid:239)ugi Identity Zastosowanie migracji Opcja 1. — aktualizacja Opcja 2. — usuni(cid:218)cie i ponowne utworzenie Wype(cid:239)nienie bazy danymi Sposoby uwierzytelniania Sesje Tokeny Sygnatury Uwierzytelnianie dwuetapowe Wnioski Implementacja uwierzytelniania JWT Dodanie us(cid:239)ugi uwierzytelniania do klasy startowej Aktualizacja plików AppSettings Klasa TokenController Aktualizacja klasy BaseApiController Dodanie klasy TokenController Klasa TokenRequestViewModel Klasa TokenResponseViewModel Test narz(cid:218)dziem Postman Formularz logowania w Angularze Interfejs TokenResponse Klasa AuthService Nowa wersja komponentu LoginComponent Dodanie tokena do nag(cid:239)ówka (cid:285)(cid:200)dania HTTP Wymuszenie autoryzacji Dostosowanie klienta Komponent NavMenuComponent Komponent QuizComponent Ochrona serwera Pobranie identyfikatora aktualnego u(cid:285)ytkownika Sprawdzenie uwierzytelniania na styku klient-serwer Poruszana tematyka Podsumowanie Spis tre(cid:286)ci 332 333 334 335 335 335 336 337 338 343 343 344 344 345 345 346 346 348 349 349 349 350 350 352 353 354 355 358 359 359 361 361 361 365 373 376 376 377 379 380 380 381 382 383 9 Poleć książkęKup książkę Spis tre(cid:286)ci Rozdzia(cid:239) 9. Tematy zaawansowane Wygasanie tokena i tokeny od(cid:258)wie(cid:285)ania Czym jest token od(cid:258)wie(cid:285)ania? Zadania po stronie serwerowej Dodanie encji dla tokena Implementacja tokena od(cid:258)wie(cid:285)ania Zadania po stronie klienckiej Aktualizacja interfejsu TokenResponse Aktualizacja klasy AuthService Dodanie klasy AuthResponseInterceptor Test dzia(cid:239)ania aplikacji Rejestracja nowego u(cid:285)ytkownika Zadania po stronie serwerowej Klasa UserController Klasa UserViewModel Zadania po stronie klienckiej Interfejs User Klasa RegisterComponent Plik AppModule Komponent LoginComponent Komponent NavMenu Test dzia(cid:239)ania aplikacji Uwierzytelnianie dzi(cid:218)ki firmom trzecim Dzia(cid:239)anie uwierzytelniania OAuth2 Mechanizm jawny czy niejawny? Wnioski Logowanie do Facebooka Tworzenie aplikacji Facebooka Mechanizm niejawny Aktualizacja klasy TokenController Dodanie komponentu LoginFacebookComponent Test dzia(cid:239)ania aplikacji Mechanizm jawny Instalacja pakietu Authentication.Facebook Konfiguracja us(cid:239)ugi uwierzytelniania poprzez Facebooka Aktualizacja pliku appsettings.json Aktualizacja klasy TokenController Komponent LoginExternalProvider Test dzia(cid:239)ania aplikacji Poruszana tematyka Podsumowanie Rozdzia(cid:239) 10. Prace wyko(cid:241)czeniowe i wdro(cid:285)enie Przej(cid:258)cie na SQL Server Instalacja SQL Server 2017 Express Edition Instalacja SQL Server Management Studio Konfiguracja bazy danych 10 385 385 386 387 387 389 394 395 395 396 399 400 400 400 402 402 403 403 406 407 407 407 409 409 410 412 412 412 415 416 421 427 427 428 428 429 430 435 438 439 439 441 441 442 442 443 Poleć książkęKup książkę Dodanie konfiguracji po(cid:239)(cid:200)czenia z baz(cid:200) SQL Server Modyfikacja konfiguracji po(cid:239)(cid:200)czenia z baz(cid:200) danych Dodanie produkcyjnego adresu URL u zewn(cid:218)trznych dostawców Aktualizacja pliku launchSettings.json Publikacja aplikacji internetowej Tworzenie profilu publikacji Publikacja poprzez protokó(cid:239) FTP Profil publikacji do folderu Publikacja aplikacji internetowej Konfiguracja serwera i IIS Instalacja modu(cid:239)u ASP.NET Core dla IIS Dodanie nowej witryny Konfiguracja puli aplikacji Uruchamianie silnika Analiza typowych b(cid:239)(cid:218)dów po wdro(cid:285)eniu Przeanalizowanie komunikatu w przegl(cid:200)darce Narz(cid:218)dzie Event Viewer Modu(cid:239) logowania w ASP.NET Core Sprawdzenie serwera Kestrel Wy(cid:239)(cid:200)czenie renderowania po stronie serwera Poruszana tematyka Podsumowanie Skorowidz Spis tre(cid:286)ci 446 447 447 448 448 449 450 451 451 452 452 453 455 456 457 457 461 461 462 464 464 465 467 11 Poleć książkęKup książkę Spis tre(cid:286)ci 12 Poleć książkęKup książkę 2 Cz(cid:218)(cid:258)(cid:202) serwerowa wykorzystuj(cid:200)ca .NET Core Skoro uda(cid:239)o nam si(cid:218) uruchomi(cid:202) szkielet aplikacji, zacznijmy analizowa(cid:202) mechanizm interakcji klient-serwer wykorzystywany przez oba frameworki. Innymi s(cid:239)owy, omówmy, w jaki sposób Angular b(cid:218)dzie pobiera(cid:239) dane z .NET Core za pomoc(cid:200) ca(cid:239)kowicie nowej struktury obs(cid:239)uguj(cid:200)cej jednocze(cid:258)nie wersje MVC i API. W tej chwili nie b(cid:218)dziemy zajmowa(cid:202) si(cid:218) tym, w jaki sposób .NET Core otrzyma dane z obiektów sesyjnych, lokalnych plików, relacyjnych baz danych itp. Tym tematem zajmiemy si(cid:218) pó(cid:283)niej. Na razie skupimy si(cid:218) na przyk(cid:239)adowych statycznych danych, by(cid:258) móg(cid:239) lepiej zrozumie(cid:202), jak dzia(cid:239)a wzajemna komunikacja mi(cid:218)dzy Angularem i .NET Core. Wykorzystamy dobrze ustrukturyzowa- ny, wysoce konfigurowalny i wygodny interfejs, który stosuje rozwi(cid:200)zania podobne do tych, jakie stosowa(cid:239) przyk(cid:239)adowy kontroler SampleDataController do(cid:239)(cid:200)czony do szablonu SPA omówionego w rozdziale 1. Przep(cid:239)yw danych Jak zapewne wiesz, natywna aplikacja webowa dzia(cid:239)aj(cid:200)ca zgodnie z modelem SPA obs(cid:239)uguje komunikacj(cid:218) mi(cid:218)dzy klientem i serwerem w nast(cid:218)puj(cid:200)cy sposób: Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera W tworzonej aplikacji rol(cid:218) pliku index.html przedstawionego na schemacie odgrywa widok /Views/Index.cshtml zwracany przez akcj(cid:218) Index znajduj(cid:200)c(cid:200) si(cid:218) w kontrolerze HomeController. Ogólna zasada dzia(cid:239)ania pozostaje jednak taka sama. Je(cid:258)li zastanawiasz si(cid:218), czym s(cid:200) asynchroniczne (cid:285)(cid:200)dania danych, odpowied(cid:283) jest bardzo prosta — to dowolne tre(cid:258)ci, których pobranie wymaga komunikacji z serwerem. Cz(cid:218)sto taka komunikacja jest wynikiem akcji u(cid:285)ytkownika, np. klikni(cid:218)cia przycisku, edycji danych w formularzu, klikni(cid:218)cia (cid:239)(cid:200)cza przej(cid:258)cia do innej strony, wys(cid:239)ania formularza itp. Je(cid:285)eli realizowane zadanie jest bardzo proste (lub wymaga minimalnej ilo(cid:258)ci danych), klient najcz(cid:218)(cid:258)ciej potrafi obs(cid:239)u(cid:285)y(cid:202) je samodzielnie bez dodatkowej komunikacji. Takie proste zadania to na przyk(cid:239)ad ukrycie lub wy(cid:258)wietlenie cz(cid:218)(cid:258)ci danych, przej(cid:258)cie do innej cz(cid:218)(cid:258)ci tej samej strony, walidacja danych wpisanych w formularzu przed ich wys(cid:239)aniem itp. Przedstawiony schemat pokazuje, co musimy zrobi(cid:202) — zdefiniowa(cid:202) i zaimplementowa(cid:202) wzo- rzec obs(cid:239)ugi (cid:285)(cid:200)da(cid:241) bazuj(cid:200)cych na formacie JSON i przesy(cid:239)a(cid:202) do klienta wymagane dane. Poniewa(cid:285) zdecydowali(cid:258)my si(cid:218) na aplikacj(cid:218) wymagaj(cid:200)c(cid:200) wielu ró(cid:285)nych rodzajów informacji, z pewno(cid:258)ci(cid:200) wykonamy kilka standardowych zestawów (cid:285)(cid:200)da(cid:241) typu CRUD zwi(cid:200)zanych z obs(cid:239)ugiwanymi przez aplikacje typami danych. Dla osób, które jeszcze nie s(cid:239)ysza(cid:239)y o CRUD — to skrót od Create-Read-Update-Delete, czyli czterech podstawowych funkcji zwi(cid:200)zanych z trwa(cid:239)ym zapisem danych. Skrót ten sta(cid:239) si(cid:218) popular- ny po tym, jak James Martin wspomnia(cid:239) o nim w ksi(cid:200)(cid:285)ce Managing the Database Environment wydanej w 1983 roku. Obecnie pojawia si(cid:218) bardzo cz(cid:218)sto w kontek(cid:258)cie programowania API. 80 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core Gdy we(cid:283)miemy pod uwag(cid:218) plan dzia(cid:239)ania aplikacji opisany w rozdziale 1., mo(cid:285)emy szybko zdefiniowa(cid:202) podstawowe rodzaje tre(cid:258)ci, jakich b(cid:218)dziemy wymaga(cid:202). Mamy wi(cid:218)c quizy, które b(cid:218)d(cid:200) stanowi(cid:239)y g(cid:239)ówny rodzaj tre(cid:258)ci prezentowanej w aplikacji. Quiz sk(cid:239)ada si(cid:218) z pyta(cid:241) (jednego lub wi(cid:218)kszej liczby), a ka(cid:285)de pytanie ma list(cid:218) odpowiedzi. Z quizem powi(cid:200)zane s(cid:200) te(cid:285) wyniki. W pewnym momencie do aplikacji b(cid:218)dziemy musieli te(cid:285) wprowadzi(cid:202) u(cid:285)ytkowników, co pozwoli doda(cid:202) mechanizm uwierzytelniania i autoryzacji, a tym samym definiowa(cid:202), kto ma prawo do przegl(cid:200)dania, edycji lub usuni(cid:218)cia okre(cid:258)lonych danych. Dla ka(cid:285)dego z wymienionych rodzajów danych przygotujemy odpowiedni zestaw (cid:285)(cid:200)da(cid:241) umo(cid:285)li- wiaj(cid:200)cych przegl(cid:200)danie listy wpisów, edycj(cid:218) i pobieranie pojedynczego wpisu, a tak(cid:285)e usuwanie wybranego wpisu. Zanim przejdziemy dalej, przyjrzyjmy si(cid:218) dok(cid:239)adniej pojedynczemu wys(cid:239)anemu przez klienta cyklowi (cid:285)(cid:200)dania danych, który powoduje przygotowanie przez serwer odpowiedzi w formacie JSON. Najcz(cid:218)(cid:258)ciej taki cykl nazywamy skrótowo cyklem (cid:285)(cid:200)danie-odpowied(cid:283). Aby zareagowa(cid:202) na dowolne (cid:285)(cid:200)danie danych wys(cid:239)ane przez klienta, musimy zdefiniowa(cid:202) po stro- nie serwera kontroler o nast(cid:218)puj(cid:200)cych mo(cid:285)liwo(cid:258)ciach: (cid:81) odczytu i (lub) zapisu danych przy u(cid:285)yciu warstwy dost(cid:218)pu do danych; (cid:81) organizacji tych danych na podstawie wygodnego modelu widoku z opcj(cid:200) serializacji do formatu JSON; (cid:81) serializacji modelu widoku i wys(cid:239)ania go do klienta jako odpowiedzi. 81 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera Na podstawie wymienionych punktów (cid:239)atwo doj(cid:258)(cid:202) do wniosku, (cid:285)e model widoku (ViewModel) to kluczowy element. Nie zawsze jednak jest on najwa(cid:285)niejszy — wszystko zale(cid:285)y od rodzaju two- rzonego projektu. Zanim przejdziemy dalej, przyjrzyjmy si(cid:218) bli(cid:285)ej obiektom ViewModel. Zadania modelu widoku Wiemy, (cid:285)e klasa ViewModel to klasa typu kontenerowego odpowiedzialna jedynie za przechowywa- nie danych kierowanych do wy(cid:258)wietlenia na stronie WWW. W standardowych aplikacjach ASP.NET dzia(cid:239)aj(cid:200)cych na zasadach MVC model widoku jest tworzony przez kontroler w odpo- wiedzi na (cid:285)(cid:200)danie GET na podstawie danych otrzymanych z modelu. Utworzony model widoku trafia do widoku, gdzie najcz(cid:218)(cid:258)ciej s(cid:239)u(cid:285)y do wype(cid:239)nienia zawarto(cid:258)ci strony lub pól formularzy. G(cid:239)ównym powodem tworzenia modelu widoku zamiast bezpo(cid:258)redniego u(cid:285)ycia encji modelu jest ch(cid:218)(cid:202) przekazania tylko tych w(cid:239)a(cid:258)ciwo(cid:258)ci, z których rzeczywi(cid:258)cie chcemy skorzysta(cid:202). Pozosta(cid:239)e w(cid:239)a- (cid:258)ciwo(cid:258)ci obiektów dziedzinowych zostan(cid:200) pomini(cid:218)te, wi(cid:218)c ilo(cid:258)(cid:202) przesy(cid:239)anych danych zmniejszy si(cid:218). Dodatkow(cid:200) zalet(cid:200) jest zwi(cid:218)kszone bezpiecze(cid:241)stwo, bo wybrane pola z danymi wra(cid:285)liwymi mo(cid:285)emy (cid:239)atwo wykluczy(cid:202) z przesy(cid:239)ania protoko(cid:239)em HTTP. W standardowym kontek(cid:258)cie API webowego, gdzie dane s(cid:200) przekazywane w (cid:239)atwych do seriali- zacji formatach takich jak JSON lub XML, model widoku mo(cid:285)na w wielu sytuacjach z powo- dzeniem zast(cid:200)pi(cid:202) dynamicznym obiektem tworzonym jednorazowo na potrzeby konkretnej odpowiedzi, na przyk(cid:239)ad: var response = new { Id = 1 , Title = Tytu(cid:239) , Description = Opis }; Takie podej(cid:258)cie sprawdza si(cid:218) w ma(cid:239)ych projektach lub prototypach, gdzie tworzenie jednej klasy lub wielu klas modeli widoków by(cid:239)oby strat(cid:200) czasu. W naszym przypadku jednak projekt znacz(cid:200)co skorzysta na dobrze zdefiniowanych, silnie typowanych strukturach modeli widoków, nawet je(cid:258)li za ka(cid:285)dym razem b(cid:218)d(cid:200) one konwertowane na format JSON. Pierwszy model widoku Skoro znasz ju(cid:285) zasady rz(cid:200)dz(cid:200)ce cyklem (cid:285)(cid:200)danie-odpowied(cid:283), mo(cid:285)emy przyst(cid:200)pi(cid:202) do budowania pierwszych elementów. Cho(cid:202) cz(cid:218)(cid:258)(cid:202) kliencka jeszcze nie istnieje, (cid:239)atwo odgadn(cid:200)(cid:202), czego b(cid:218)- dziemy potrzebowali — metod CRUD dla ka(cid:285)dego z rodzajów tre(cid:258)ci wymienionych kilka akapitów wcze(cid:258)niej. 82 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core Osoby zaznajomione z systemem ASP.NET MVC zapewne od razu chcia(cid:239)yby przyst(cid:200)pi(cid:202) do utwo- rzenia osobnego kontrolera dla ka(cid:285)dego rodzaju tre(cid:258)ci. Zanim jednak przejdziemy do kontrolerów, warto utworzy(cid:202) modele widoków, aby obs(cid:239)uga danych odbywa(cid:239)a si(cid:218) od razu przy u(cid:285)yciu silnego typowania. Klasa QuizViewModel Zacznijmy od najwa(cid:285)niejszego rodzaju danych w tworzonej aplikacji. B(cid:218)dzie to równie(cid:285) najbar- dziej rozbudowany element. Chwileczk(cid:218), ale dlaczego zaczynamy od modelu widoku, skoro nie mamy jeszcze modelu danych? Sk(cid:200)d uzyskamy dane? To nietrywialne pytanie wymaga odpowiedzi, zanim przejdziemy dalej. Jedn(cid:200) z ogromnych zalet budowania aplikacji internetowych za pomoc(cid:200) ASP.NET i Angulara jest to, (cid:285)e mo(cid:285)emy pisa(cid:202) kod bez przejmowania si(cid:218) (cid:283)ród(cid:239)ami danych. Mo(cid:285)emy zaj(cid:200)(cid:202) si(cid:218) nimi pó(cid:283)niej, gdy b(cid:218)dziemy wiedzie(cid:202), czego tak naprawd(cid:218) potrzebujemy. Oczywi(cid:258)cie nie jest to wymóg i równie dobrze mogliby(cid:258)my zacz(cid:200)(cid:202) od (cid:283)róde(cid:239) danych, je(cid:258)li: (cid:81) dok(cid:239)adnie wiemy, co chcemy wykona(cid:202); (cid:81) posiadamy ju(cid:285) odpowiednie zestawy encji i (lub) zdefiniowane oraz wype(cid:239)nione struktury danych; (cid:81) jeste(cid:258)my przyzwyczajeni do zaczynania tworzenia aplikacji od danych, a nie od interfejsu u(cid:285)ytkownika. Ka(cid:285)dy z wymienionych powodów jest s(cid:239)uszny — nie spowoduje, (cid:285)e zostaniemy zwolnieni. Z dru- giej strony rozpocz(cid:218)cie prac najpierw nad cz(cid:218)(cid:258)ci(cid:200) klienck(cid:200) pozwoli rozwia(cid:202) od razu wiele w(cid:200)tpliwo(cid:258)ci zwi(cid:200)zanych ze sposobem dzia(cid:239)ania aplikacji, a tym samym u(cid:239)atwi podj(cid:218)cie decyzji co do wymaganych rodzajów danych. Buduj(cid:200)c t(cid:218) aplikacj(cid:218), skorzystamy w(cid:239)a(cid:258)nie z tego podej(cid:258)cia, zaczniemy wi(cid:218)c prace nad klas(cid:200) QuizViewModel, cho(cid:202) nie mamy jeszcze klas (cid:283)róde(cid:239) danych i encji. Z poziomu panelu Eksplorator rozwi(cid:200)za(cid:241) (Solution Explorer) kliknij prawym klawiszem myszy w(cid:218)ze(cid:239) TestMakerFreeWebApp (g(cid:239)ówna aplikacja), a nast(cid:218)pnie utwórz nowy folder /ViewModels/. Nast(cid:218)pnie kliknij prawym klawiszem myszy nowo utworzony folder i wykonaj standardowe polecenie Dodaj/Nowy element (Add/New Item). W widoku drzewa wybierz ASP.NET Core/Kod (ASP.NET Core/Code), zaznacz element Klasa (Class), nadaj mu nazw(cid:218) QuizViewModel.cs. Kliknij przycisk Dodaj (Add), aby utworzy(cid:202) nowy plik w folderze /ViewModels/. Otwórz nowy plik i zamie(cid:241) jego oryginaln(cid:200) tre(cid:258)(cid:202) na poni(cid:285)sz(cid:200): using Newtonsoft.Json; using System; using System.Collections.Generic; 83 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera using System.ComponentModel; using System.Linq; using System.Threading.Tasks; namespace TestMakerFreeWebApp.ViewModels { [JsonObject(MemberSerialization.OptOut)] public class QuizViewModel { #region Konstruktor public QuizViewModel() { } #endregion #region W(cid:239)a(cid:258)ciwo(cid:258)ci public int Id { get; set; } public string Title { get; set; } public string Description { get; set; } public string Text { get; set; } public string Notes { get; set; } [DefaultValue(0)] public int Type { get; set; } [DefaultValue(0)] public int Flags { get; set; } public string UserId { get; set; } [JsonIgnore] public int ViewCount { get; set; } public DateTime CreatedDate { get; set; } public DateTime LastModifiedDate { get; set; } #endregion } } Jak mo(cid:285)esz si(cid:218) przekona(cid:202), klasa przypomina typowy obiekt POCO z raczej standardowym zesta- wem w(cid:239)a(cid:258)ciwo(cid:258)ci. Obiekt quizu b(cid:218)dzie mia(cid:239) tytu(cid:239) (Title), opis (Description) itp. W tworzonym obiekcie nadal brakuje kilku elementów, przede wszystkim odniesie(cid:241) do pyta(cid:241), odpowiedzi i wy- ników — dodamy je na dalszym etapie prac. Klasa QuizController Przejd(cid:283)my teraz do utworzenia klasy QuizController. 1. Z poziomu panelu Eksplorator rozwi(cid:200)za(cid:241) (Solution Explorer) otwórz folder /Controllers/. 84 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core 2. Nast(cid:218)pnie kliknij prawym klawiszem myszy folder i wykonaj standardowe polecenie Dodaj/Nowy element (Add/New Item). Nie korzystaj z polecenia Dodaj/Kontroler (Add/Controller), bo spowoduje to uruchomienie kreatora, który doda do projektu kilka zale(cid:285)no(cid:258)ci, a tego na razie nie potrzebujemy. 3. W widoku drzewa wybierz ASP.NET Core/Sie(cid:202) Web (ASP.NET Core/Web), zaznacz Klasa kontrolera interfejsu API (Web API Controller Class), nadaj nowemu plikowi nazw(cid:218) QuizController.cs i kliknij Dodaj (Add), aby doda(cid:202) nowy plik w folderze /Controllers/. Plik pojawi si(cid:218) obok istniej(cid:200)cych ju(cid:285) plików HomeController.cs i SampleDataController.cs, o których wspomnia(cid:239)em w rozdziale 1. Kontroler zosta(cid:239) utworzony z kilkoma przyk(cid:239)adowymi metodami, których nie potrzebujemy. Usu(cid:241) ca(cid:239)(cid:200) istniej(cid:200)c(cid:200) zawarto(cid:258)(cid:202) pliku i wstaw na jej miejsce poni(cid:285)szy kod: using System; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using TestMakerFreeWebApp.ViewModels; using System.Collections.Generic; using System.Linq; namespace TestMakerFreeWebApp.Controllers { [Route( api/[controller] )] public class QuizController : Controller { // GET api/quiz/latest [HttpGet( Latest/{num?} )] public IActionResult Latest(int num = 10) { var sampleQuizzes = new List QuizViewModel (); // Dodaj pierwszy przyk(cid:225)adowy quiz sampleQuizzes.Add(new QuizViewModel() { Id = 1, Title = Któr(cid:200) postaci(cid:200) z Shingeki No Kyojin (Atak tytanów) jeste(cid:258)? , Description = Test osobowo(cid:258)ci bazuj(cid:200)cy na anime , CreatedDate = DateTime.Now, LastModifiedDate = DateTime.Now }); // Dodaj kilka nast(cid:266)pnych przyk(cid:225)adowych quizów for (int i = 2; i = num; i++) { sampleQuizzes.Add(new QuizViewModel() { 85 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera Id = i, Title = String.Format( Przyk(cid:239)adowy quiz {0} , i), Description = To jest przyk(cid:239)adowy quiz , CreatedDate = DateTime.Now, LastModifiedDate = DateTime.Now }); } // Przeka(cid:298) wyniki w formacie JSON return new JsonResult( sampleQuizzes, new JsonSerializerSettings() { Formatting = Formatting.Indented }); } } } Przyjrzyjmy si(cid:218) dok(cid:239)adniej dodanemu kodowi. Zdefiniowali(cid:258)my metod(cid:218) Latest przyjmuj(cid:200)c(cid:200) pojedynczy, opcjonalny parametr typu int o nazwie num i warto(cid:258)ci domy(cid:258)lnej 10. Metoda przyjmuje dowolne (cid:285)(cid:200)danie GET zgodne z zasadami zdefi- niowanymi w atrybucie HttpGet. Takie rozwi(cid:200)zanie nazywa si(cid:218) routingiem atrybutowym, o któ- rym wi(cid:218)cej informacji znajdziesz w dalszej cz(cid:218)(cid:258)ci rozdzia(cid:239)u. Na razie skupmy si(cid:218) na zawarto(cid:258)ci omawianej metody. Dzia(cid:239)anie kodu jest bardzo proste, bo nie mamy (jeszcze) (cid:283)ród(cid:239)a danych — po prostu zwracamy kilka przyk(cid:239)adowych obiektów QuizViewModel. Cho(cid:202) tylko symulujemy prawdziw(cid:200) odpowied(cid:283), czynimy to w sposób ustrukturyzowany i wiarygodny, czyli respektujemy limit zwracanych ele- mentów, a tak(cid:285)e przekazujemy ró(cid:285)ni(cid:200)ce si(cid:218) mi(cid:218)dzy sob(cid:200) elementy. W zasadzie stosujemy to samo podstawowe podej(cid:258)cie, które zosta(cid:239)o zaproponowane w pliku SampleDataController.cs wy- generowanym przy u(cid:285)yciu szablonu Angular SPA w rozdziale 1. Zauwa(cid:285), (cid:285)e zwracamy warto(cid:258)ci typu JsonResult, co jest najlepszym rozwi(cid:200)zaniem, gdy korzystamy z klas modeli widoków z atrybutem JsonObject zapewnianym przez framework Newtonsoft.Json. To zdecydowanie lepsze rozwi(cid:200)zanie ni(cid:285) zwracanie zwyk(cid:239)ego typu string lub Ienumerable (cid:180) string , bo poza automatyczn(cid:200) serializacj(cid:200) danych ustawione zostan(cid:200) równie(cid:285) niezb(cid:218)dne nag(cid:239)ówki odpowiedzi (Content-Type, charset itp.). Dodatkowe metody akcji Zanim przejdziemy do innych tematów, skorzystajmy z okazji i dodajmy jeszcze dwie metody akcji do klasy QuizController, co pozwoli zasymulowa(cid:202) ró(cid:285)ne strategie pobierania danych: otrzymy- wanie quizów u(cid:239)o(cid:285)onych alfabetycznie lub ca(cid:239)kowicie losowych. 86 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core Metoda ByTitle Umie(cid:258)(cid:202) poni(cid:285)szy kod tu(cid:285) po metodzie Latest(): /// summary /// GET: api/quiz/ByTitle /// Pobiera {num} quizów posortowanych po tytule (od A do Z) /// /summary /// param name= num liczba quizów do pobrania /param /// returns {num} quizów posortowanych po tytule /returns [HttpGet( ByTitle/{num:int?} )] public IActionResult ByTitle(int num = 10) { var sampleQuizzes = ((JsonResult)Latest(num)).Value as List QuizViewModel ; return new JsonResult( sampleQuizzes.OrderBy(t = t.Title), new JsonSerializerSettings() { Formatting = Formatting.Indented }); } Nowa metoda wewn(cid:218)trznie u(cid:285)ywa metody Latest, która zwraca list(cid:218) przyk(cid:239)adowych quizów, a nast(cid:218)pnie sortuje je alfabetycznie i zwraca now(cid:200) list(cid:218). Metoda Random() W bardzo podobny sposób zaimplementujemy metod(cid:218) Random(): /// summary /// GET: api/quiz/mostViewed /// Pobiera {num} losowych quizów /// /summary /// param name= num liczba quizów do pobrania /param /// returns {num} losowych quizów /returns [HttpGet( Random/{num:int?} )] public IActionResult Random(int num = 10) { var sampleQuizzes = ((JsonResult)Latest(num)).Value as List QuizViewModel ; return new JsonResult( sampleQuizzes.OrderBy(t = Guid.NewGuid()), new JsonSerializerSettings() { Formatting = Formatting.Indented }); } 87 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera Sprawdzenie, czy wszystko dzia(cid:239)a Wypróbujmy nowy kontroler, uruchamiaj(cid:200)c aplikacj(cid:218) w trybie debugowania i wpisuj(cid:200)c w pasku adresu przegl(cid:200)darki internetowej poni(cid:285)szy adres: http://localhost: port /api/quiz/latest/3 Je(cid:258)li wszystko zosta(cid:239)o wykonane poprawnie, powinien ukaza(cid:202) si(cid:218) poni(cid:285)szy wynik. Zwró(cid:202) uwag(cid:218), (cid:285)e w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) ViewCount nie pojawia si(cid:218) w wynikach w formacie JSON. To celowe dzia(cid:239)anie, bo atrybut zosta(cid:239) oznaczony jako JsonIgnore, czyli jest pomijany na etapie serializacji. Pierwszy kontroler dzia(cid:239)a bardzo dobrze. Doce(cid:241) ten fakt! Ju(cid:285) niebawem b(cid:218)dzie odpowiada(cid:239) w przyk(cid:239)adowej aplikacji za wszystkie operacje zwi(cid:200)zane z quizami. 88 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core Dodawanie pozosta(cid:239)ych kontrolerów Skoro wiesz ju(cid:285), jak dodawa(cid:202) kontrolery i modele widoków, dodajmy po parze kontroler- model dla ka(cid:285)dego z pozosta(cid:239)ych typów danych. Aby si(cid:218) nie powtarza(cid:202), pomin(cid:218) opisy tworzenia plików i po prostu zaprezentuj(cid:218) pokrótce opisany kod (cid:283)ród(cid:239)owy, który nale(cid:285)y umie(cid:258)ci(cid:202) w ka(cid:285)dym z plików. Klasa QuestionViewModel Czym by(cid:239)by quiz bez pyta(cid:241)? Dodaj plik QuestionViewModel.cs w folderze /ViewModels/ i umie(cid:258)(cid:202) w nim poni(cid:285)szy kod: using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Threading.Tasks; namespace TestMakerFreeWebApp.ViewModels { [JsonObject(MemberSerialization.OptOut)] public class QuestionViewModel { #region Konstruktor public QuestionViewModel() { } #endregion #region W(cid:239)a(cid:258)ciwo(cid:258)ci public int Id { get; set; } public int QuizId { get; set; } public string Text { get; set; } public string Notes { get; set; } [DefaultValue(0)] public int Type { get; set; } [DefaultValue(0)] public int Flags { get; set; } [JsonIgnore] public DateTime CreatedDate { get; set; } public DateTime LastModifiedDate { get; set; } #endregion } } 89 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera Kod bardzo przypomina skonstruowan(cid:200) wcze(cid:258)niej klas(cid:218) QuizViewModel, ale u(cid:285)ywa innych w(cid:239)a(cid:258)ci- wo(cid:258)ci. Jedn(cid:200) z nich jest QuizId, co stanowi raczej oczywisty dodatek, bo ka(cid:285)de pytanie musi by(cid:202) powi(cid:200)zane z quizem w relacji jeden do wielu. Ka(cid:285)dy quiz b(cid:218)dzie sk(cid:239)ada(cid:239) si(cid:218) z wielu pyta(cid:241). Klasa QuestionController Klasa QuestionController, podobnie jak wcze(cid:258)niej klasa QuizController, powinna si(cid:218) znale(cid:283)(cid:202) w folderze /Controllers/. Umie(cid:258)(cid:202) j(cid:200) w pliku o nazwie QuestionController.cs: using System; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using TestMakerFreeWebApp.ViewModels; using System.Collections.Generic; namespace TestMakerFreeWebApp.Controllers { [Route( api/[controller] )] public class QuestionController : Controller { // GET api/question/all [HttpGet( All/{quizId} )] public IActionResult All(int quizId) { var sampleQuestions = new List QuestionViewModel (); // Dodaj pierwsze przyk(cid:225)adowe pytanie sampleQuestions.Add(new QuestionViewModel() { Id = 1, QuizId = quizId, Text = Co cenisz w swoim (cid:285)yciu najbardziej? , CreatedDate = DateTime.Now, LastModifiedDate = DateTime.Now }); // Dodaj kilka innych przyk(cid:225)adowych pyta(cid:276) for (int i = 2; i = 5; i++) { sampleQuestions.Add(new QuestionViewModel() { Id = i, QuizId = quizId, Text = String.Format( Przyk(cid:239)adowe pytanie {0} , i), CreatedDate = DateTime.Now, LastModifiedDate = DateTime.Now }); } 90 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core // Przeka(cid:298) wyniki w formacie JSON return new JsonResult( sampleQuestions, new JsonSerializerSettings() { Formatting = Formatting.Indented }); } } } Zwró(cid:202) uwag(cid:218), (cid:285)e zamiast metody Latest zdefiniowanej w QuizController u(cid:285)yli(cid:258)my tym razem metody All, która zwraca wszystkie pytania zwi(cid:200)zane z okre(cid:258)lonym quizem na podstawie przeka- zanego identyfikatora (quizId). Implementacja metody Latest nie mia(cid:239)aby du(cid:285)ego sensu, bo pytania same w sobie nie maj(cid:200) (cid:285)ad- nej warto(cid:258)ci. Powinny by(cid:202) pobierane i prezentowane u(cid:285)ytkownikowi tylko w powi(cid:200)zaniu z quizem, którego dotycz(cid:200). W takiej sytuacji u(cid:285)ycie metody All ma znacznie wi(cid:218)kszy sens. Klasa AnswerViewModel Odpowiedzi s(cid:200) w relacji jeden do wielu z pytaniami, podobnie jak pytania z quizami, kod klasy AnswerViewModel bardzo przypomina wi(cid:218)c kod klasy QuestionViewModel: using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; namespace TestMakerFreeWebApp.ViewModels { [JsonObject(MemberSerialization.OptOut)] public class AnswerViewModel { #region Konstruktor public AnswerViewModel() { } #endregion #region W(cid:239)a(cid:258)ciwo(cid:258)ci public int Id { get; set; } public int QuizId { get; set; } public int QuestionId { get; set; } public string Text { get; set; } public string Notes { get; set; } 91 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera [DefaultValue(0)] public int Type { get; set; } [DefaultValue(0)] public int Flags { get; set; } [DefaultValue(0)] public int Value { get; set; } [JsonIgnore] public DateTime CreatedDate { get; set; } public DateTime LastModifiedDate { get; set; } #endregion } } S(cid:200) tylko dwie istotne ró(cid:285)nice: (cid:81) pojawi(cid:239)a si(cid:218) w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) odnosz(cid:200)ca si(cid:218) do QuestionId, co pozwala na poprawne okre(cid:258)lenie relacji mi(cid:218)dzy odpowiedzi(cid:200) i pytaniem; (cid:81) pojawi(cid:239)a si(cid:218) w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) Value, która pos(cid:239)u(cid:285)y nam pó(cid:283)niej do okre(cid:258)lenia warto(cid:258)ci punktowej odpowiedzi. Klasa AnswerController Oto kod dotycz(cid:200)cy klasy AnswerController: using System; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using TestMakerFreeWebApp.ViewModels; using System.Collections.Generic; namespace TestMakerFreeWebApp.Controllers { [Route( api/[controller] )] public class AnswerController : Controller { // GET api/answer/all [HttpGet( All/{questionId} )] public IActionResult All(int questionId) { var sampleAnswers = new List AnswerViewModel (); // Dodaj pierwsz(cid:261) przyk(cid:225)adow(cid:261) odpowied(cid:296) sampleAnswers.Add(new AnswerViewModel() { Id = 1, QuestionId = questionId, Text = Przyjació(cid:239) i rodzin(cid:218) , CreatedDate = DateTime.Now, 92 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core LastModifiedDate = DateTime.Now }); // Dodaj kilka nast(cid:266)pnych przyk(cid:225)adowych odpowiedzi for (int i = 2; i = 5; i++) { sampleAnswers.Add(new AnswerViewModel() { Id = i, QuestionId = questionId, Text = String.Format( Przyk(cid:239)adowa odpowied(cid:283) {0} , i), CreatedDate = DateTime.Now, LastModifiedDate = DateTime.Now }); } // Przeka(cid:298) wyniki w formacie JSON return new JsonResult( sampleAnswers, new JsonSerializerSettings() { Formatting = Formatting.Indented }); } } } Obecnie ten kod jest bardzo podobny do kodu klasy QuestionController, cho(cid:202) w przysz(cid:239)o(cid:258)ci z pewno(cid:258)ci(cid:200) ulegnie zmianie. Klasa ResultViewModel Kontynuujmy prac(cid:218) i przygotujmy klas(cid:218) ResultViewModel: using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; namespace TestMakerFreeWebApp.ViewModels { [JsonObject(MemberSerialization.OptOut)] public class ResultViewModel { #region Konstruktor public ResultViewModel() { 93 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera } #endregion #region W(cid:239)a(cid:258)ciwo(cid:258)ci public int Id { get; set; } public int QuizId { get; set; } public string Text { get; set; } public string Notes { get; set; } [DefaultValue(0)] public int Type { get; set; } [DefaultValue(0)] public int Flags { get; set; } [JsonIgnore] public DateTime CreatedDate { get; set; } public DateTime LastModifiedDate { get; set; } #endregion } } I tym razem kod jest bardzo podobny do wcze(cid:258)niej przedstawionego. Pewne zmiany pojawi(cid:200) si(cid:218) w przysz(cid:239)o(cid:258)ci. Klasa ResultController Umie(cid:258)(cid:202) w odpowiednim pliku poni(cid:285)szy kod klasy ResultController: using System; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using TestMakerFreeWebApp.ViewModels; using System.Collections.Generic; namespace TestMakerFreeWebApp.Controllers { [Route( api/[controller] )] public class ResultController : Controller { // GET api/question/all [HttpGet( All/{quizId} )] public IActionResult All(int quizId) { var sampleResults = new List ResultViewModel (); // Dodaj pierwszy przyk(cid:225)adowy wynik sampleResults.Add(new ResultViewModel() { Id = 1, QuizId = quizId, 94 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core Text = Co cenisz w swoim (cid:285)yciu najbardziej? , CreatedDate = DateTime.Now, LastModifiedDate = DateTime.Now }); // Dodaj kilka innych przyk(cid:225)adowych wyników for (int i = 2; i = 5; i++) { sampleResults.Add(new ResultViewModel() { Id = i, QuizId = quizId, Text = String.Format( Przyk(cid:239)adowe pytanie {0} , i), CreatedDate = DateTime.Now, LastModifiedDate = DateTime.Now }); } // Przeka(cid:298) wyniki w formacie JSON return new JsonResult( sampleResults, new JsonSerializerSettings() { Formatting = Formatting.Indented }); } } } Kod (cid:283)ród(cid:239)owy klas ResultViewModel i ResultController jest bardzo podobny do kodu (cid:283)ród(cid:239)owego klas QuestionViewModel i QuestionController. Powód jest raczej oczywisty — pytania i wyniki s(cid:200) w sposób bezpo(cid:258)redni powi(cid:200)zane z quizem; nie pojawia si(cid:218) po(cid:258)rednik, jak to mia(cid:239)o miejsce przy odpowiedziach. Skoro utworzyli(cid:258)my ju(cid:285) wszystkie niezb(cid:218)dne kontrolery i modele widoków, mo(cid:285)emy bezpiecznie pozby(cid:202) si(cid:218) pliku SampleDataController.cs, bo nie b(cid:218)dzie nam ju(cid:285) do niczego potrzebny. W panelu Eksplorator rozwi(cid:200)za(cid:241) (Solution Explorer) przejd(cid:283) do folderu /Controllers/, kliknij go prawym klawiszem myszy i usu(cid:241). Nie spowoduje to (cid:285)adnych b(cid:239)(cid:218)dów, bo cz(cid:218)(cid:258)(cid:202) klienck(cid:200), która u(cid:285)ywa(cid:239)a tego kontrolera, usun(cid:218)li(cid:258)my ju(cid:285) w rozdziale 1. Je(cid:258)li chcesz zachowa(cid:202) plik SampleDataController.cs, aby si(cid:218) na nim wzorowa(cid:202) w przysz(cid:239)o(cid:258)ci, utwórz podkatalog /Controllers/_usuniete i przenie(cid:258) do niego ten plik, czyli post(cid:200)p podobnie jak w rozdziale 1. z komponentami counter i fetchdata. Po wyczyszczeniu projektu przyjrzyjmy si(cid:218) dok(cid:239)adniej zagadnieniu routingu. To jeden z wa(cid:285)niej- szych tematów, po(cid:258)wi(cid:218)(cid:202)my mu wi(cid:218)c nieco miejsca. 95 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera Dzia(cid:239)anie routingu W rozdziale 1. wspomnia(cid:239)em o tym, (cid:285)e potoki ASP.NET Core zosta(cid:239)y napisane ca(cid:239)kowicie od nowa, aby po(cid:239)(cid:200)czy(cid:202) modu(cid:239)y MVC i WebAPI w jeden lekki framework. Cho(cid:202) to bez w(cid:200)tpienia dobry kie- runek, w konsekwencji tej zmiany dosy(cid:202) szybko musimy pozna(cid:202) wiele nowych elementów. Obs(cid:239)uga routingu jest tego doskona(cid:239)ym przyk(cid:239)adem, bo nowe mechanizmy wprowadzaj(cid:200) w tym zakresie istotne zmiany wzgl(cid:218)dem rozwi(cid:200)za(cid:241) stosowanych w przesz(cid:239)o(cid:258)ci. Definiowanie routingu Zanim przejdziemy do opisów, zdefiniujmy, czym tak naprawd(cid:218) jest routing. W du(cid:285)ym skrócie: routing adresów URL to funkcjonalno(cid:258)(cid:202) cz(cid:218)(cid:258)ci serwerowej systemu, która pozwala programi(cid:258)cie obs(cid:239)ugiwa(cid:202) (cid:285)(cid:200)dania HTTP o adresach niepowi(cid:200)zanych z plikami fizycz- nymi. Technik(cid:218) t(cid:218) wykorzystuje si(cid:218) z wielu ró(cid:285)nych powodów, ale g(cid:239)ównymi s(cid:200): (cid:81) mo(cid:285)liwo(cid:258)(cid:202) zapewnienia dynamicznym stronom WWW znacz(cid:200)cych i zrozumia(cid:239)ych dla ludzi nazw, aby zwi(cid:218)kszy(cid:202) czytelno(cid:258)(cid:202) lub zoptymalizowa(cid:202) strony dla wyszukiwarek (SEO — ang. Search Engine Optimization); (cid:81) mo(cid:285)liwo(cid:258)(cid:202) zmiany nazw plików fizycznych w projekcie bez konieczno(cid:258)ci zmiany ich ogólnodost(cid:218)pnych adresów URL; (cid:81) mo(cid:285)liwo(cid:258)(cid:202) wykorzystania przekierowa(cid:241) i aliasów. Routing dawniej i dzi(cid:258) W czasach, gdy ASP.NET by(cid:239)o tylko mechanizmem Web Forms, routing by(cid:239) (cid:258)ci(cid:258)le powi(cid:200)zany z plikami fizycznymi. Aby zaimplementowa(cid:202) sensowne konwencje nazewnictwa, programi(cid:258)ci byli zmuszeni do instalacji i konfiguracji dedykowanych narz(cid:218)dzi w postaci zewn(cid:218)trznych filtrów ISAPI, takich jak ISAPI Rewrite firmy Helicontech. Od IIS7 dost(cid:218)pny jest wbudowany modu(cid:239) IIS URL Rewrite. W momencie wydania ASP.NET MVC ca(cid:239)kowicie przepisano wzorzec routingu, a programi(cid:258)ci zyskali mo(cid:285)liwo(cid:258)(cid:202) zdefiniowania w(cid:239)asnego routingu bazuj(cid:200)cego na konwencjach w dedykowanym pliku (w zale(cid:285)no(cid:258)ci od szablonu w pliku RouteConfig.cs lub Global.asax) z wykorzystaniem metody Routes.MapRoute. Dla osób u(cid:285)ywaj(cid:200)cych dawniej MVC od 1 do 5 lub WebAPI 1 i 2 poni(cid:285)szy fragment kodu b(cid:218)dzie wygl(cid:200)da(cid:239) znajomo: Routes.MapRoute( name: Default , url: {controller}/{action}/{id} , defaults: new { controller = Home , action = Index , (cid:180)id = UrlParameter.Optional } ); 96 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core Ten sposób definiowania routingu bazowa(cid:239) w ca(cid:239)o(cid:258)ci na technikach dopasowywania do wzorca, konkretny adres URL by(cid:239) wi(cid:200)zany z konkretn(cid:200) akcj(cid:200) wybranego kontrolera. By(cid:239) to tak zwany routing bazuj(cid:200)cy na konwencjach. Dopiero w ASP.NET MVC5 po raz pierwszy pojawi(cid:239) si(cid:218) routing bazuj(cid:200)cy na atrybutach. Ten sposób dzia(cid:239)ania dawa(cid:239) programistom wi(cid:218)ksz(cid:200) swobod(cid:218). Ka(cid:285)dy, kto go u(cid:285)ywa(cid:239) cho(cid:202) raz, z pewno- (cid:258)ci(cid:200) zgodzi si(cid:218), (cid:285)e stanowi(cid:239) on istotny dodatek do frameworka, bo pozwala(cid:239) okre(cid:258)li(cid:202) routing w pliku kontrolera. Nawet osoby, które standardowo stosowa(cid:239)y routing bazuj(cid:200)cy na konwencjach, korzysta(cid:239)y z routingu bazuj(cid:200)cego na atrybutach do nadpisania niektórych (cid:258)cie(cid:285)ek bez uciekania si(cid:218) do skomplikowanych wyra(cid:285)e(cid:241) regularnych: [RoutePrefix( v2Products )] public class ProductsController : Controller { [Route( v2Index )] public ActionResult Index() { return View(); } } W ASP.NET Core MVC (dawniej MVC6), gdzie ponownie ca(cid:239)kowicie przepisano ca(cid:239)y mecha- nizm routingu, routing bazuj(cid:200)cy na atrybutach sta(cid:239) si(cid:218) de facto standardem, zast(cid:218)puj(cid:200)c podej(cid:258)cie bazuj(cid:200)ce na konwencjach w wi(cid:218)kszo(cid:258)ci przyk(cid:239)adów i szablonów. Warto jednak pami(cid:218)ta(cid:202), (cid:285)e me- toda Routes.MapRoute() nadal jest dost(cid:218)pna i stanowi sensown(cid:200) opcj(cid:218), je(cid:258)li chcemy zdefiniowa(cid:202) pewien ogólny mechanizm routingu wysokiego poziomu. Bardzo dobrze wida(cid:202) to w pliku Startup.cs (istotne wiersze zosta(cid:239)y pogrubione): app.UseMvc(routes = { routes.MapRoute( name: default , template: {controller=Home}/{action=Index}/{id?} ); routes.MapSpaFallbackRoute( name: spa-fallback , defaults: new { controller = Home , action = Index }); }); Powy(cid:285)szy fragment kodu pochodzi z metody Configure i doskonale pokazuje, (cid:285)e routing bazuj(cid:200)cy na konwencjach nadal stanowi sensowne rozwi(cid:200)zanie w trakcie prac nad aplikacj(cid:200) SPA. Jedyna ró(cid:285)nica wzgl(cid:218)dem ASP.NET 4.x i wcze(cid:258)niejszych wersji polega na tym, (cid:285)e (cid:258)cie(cid:285)ki s(cid:200) kierowane bezpo(cid:258)rednio do middleware MVC, gdy dodamy je do potoku (cid:285)(cid:200)da(cid:241) HTTP jako cz(cid:218)(cid:258)(cid:202) konfigu- racji. Zapewnia to wi(cid:218)ksz(cid:200) spójno(cid:258)(cid:202). 97 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera Obs(cid:239)uga routingu w .NET Core Nowa implementacja routingu w zasadzie bazuje na dwóch metodach — services.AddMvc() i app.UseMvc() — wywo(cid:239)ywanych w pliku Startup.cs. Wykonuj(cid:200) one nast(cid:218)puj(cid:200)ce zadania: (cid:81) rejestracj(cid:218) MVC przy u(cid:285)yciu mechanizmu wstrzykiwania zale(cid:285)no(cid:258)ci wbudowanego w ASP.NET Core; (cid:81) dodanie wymaganego middleware do potoku (cid:285)(cid:200)da(cid:241) HTTP, a tak(cid:285)e (opcjonalnie) konfiguracj(cid:218) routingu domy(cid:258)lnego. Mo(cid:285)emy zobaczy(cid:202), co tak naprawd(cid:218) dzieje si(cid:218) w (cid:258)rodku aktualnej implementacji metody app.UseMvc() w kodzie frameworka (istotne wiersze zosta(cid:239)y pogrubione): public static IApplicationBuilder UseMvc( [NotNull] this IApplicationBuilder app, [NotNull] Action IRouteBuilder configureRoutes) { // Verify if AddMvc was done before calling UseMvc // We use the MvcMarkerService to make sure if all the services were added. MvcServicesHelper.ThrowIfMvcNotRegistered(app.ApplicationServices); var routes = new RouteBuilder { DefaultHandler = new MvcRouteHandler(), ServiceProvider = app.ApplicationServices }; configureRoutes(routes); // Adding the attribute route comes after running the user-code because // we want to respect any changes to the DefaultHandler. routes.Routes.Insert(0, AttributeRouting.CreateAttributeMegaRoute( routes.DefaultHandler, app.ApplicationServices)); return app.UseRouter(routes.Build()); } Zalet(cid:200) obecnego podej(cid:258)cia jest to, (cid:285)e framework zajmuje si(cid:218) ca(cid:239)(cid:200) (cid:285)mudn(cid:200) prac(cid:200) dotycz(cid:200)c(cid:200) konfigu- racji domy(cid:258)lnych routingów dla akcji kontrolerów. Warto zauwa(cid:285)y(cid:202), (cid:285)e domy(cid:258)lne regu(cid:239)y stosuj(cid:200) powszechnie przyj(cid:218)te konwencje REST, nazwy akcji b(cid:218)d(cid:200) wi(cid:218)c ograniczone do Get, Post, Put i Delete. Mo(cid:285)emy powiedzie(cid:202), (cid:285)e w tej materii ASP.NET Core wprowadza (cid:258)cis(cid:239)e podej(cid:258)cie znane z WebAPI, co jednak nie powinno dziwi(cid:202), bo nowy framework ASP.NET Core zawiera wszystkie elementy poprzednich systemów. Podej(cid:258)cie typu REST to w wielu przypadkach dobre rozwi(cid:200)zanie, szczególnie je(cid:258)li zale(cid:285)y nam na pragmatycznych, publicznych API dost(cid:218)pnych dla innych programistów. Je(cid:285)eli jednak tworzymy w(cid:239)asn(cid:200) aplikacj(cid:218) i API nie musi by(cid:202) publiczne, w(cid:239)asny system routingu jest równie dobr(cid:200) opcj(cid:200). Co wi(cid:218)cej, w(cid:239)asne (cid:258)cie(cid:285)ki routingu mog(cid:200) nas nawet uchroni(cid:202) przed najprostszymi 98 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core formami ataku typu DDoS. Warto pami(cid:218)ta(cid:202), (cid:285)e routing bazuj(cid:200)cy na konwencjach i routing bazuj(cid:200)cy na atrybutach nadal jest dost(cid:218)pny, co pozwala szybko zdefiniowa(cid:202) w(cid:239)asny standard. Aby wymusi(cid:202) ten pierwszy, wystarczy rozbudowa(cid:202) kod ju(cid:285) istniej(cid:200)cy w pliku Startup.cs. Mo(cid:285)emy te(cid:285) kontynuowa(cid:202) definiowanie routingu w kodzie (cid:283)ród(cid:239)owym kontrolerów, gdzie routing bazuj(cid:200)cy na atrybutach stosuje si(cid:218) najcz(cid:218)(cid:258)ciej na poziomie kontrolera: [Route( api/[controller] )] public class ItemsController : Controller Mo(cid:285)na go jednak doda(cid:202) równie(cid:285) na poziomie metody akcji: [HttpGet( GetLatest )] public JsonResult GetLatest() Trzy sposoby routingu Podsumujmy — ASP.NET Core zapewnia nam wybór spo(cid:258)ród trzech sposobów obs(cid:239)ugi routin- gu: wymuszenia stosowania konwencji zgodnych z REST, powrotu do starego routingu bazuj(cid:200)- cego na konwencjach i dekorowania plików kontrolerów przy u(cid:285)yciu routingu bazuj(cid:200)cego na atrybutach. W naszej przyk(cid:239)adowej aplikacji wykorzystamy kombinacj(cid:218) wszystkich trzech, aby(cid:258) móg(cid:239) dobrze pozna(cid:202) ka(cid:285)dy z nich. Warto pami(cid:218)ta(cid:202), (cid:285)e (cid:258)cie(cid:285)ki zdefiniowane za pomoc(cid:200) routingu na poziomie atrybutów spowoduj(cid:200) nadpisanie dowolnych wzorców bazuj(cid:200)cych na konwencjach. Oba te mechanizmy, je(cid:258)li zostan(cid:200) u(cid:285)yte, wywo(cid:239)aj(cid:200) nadpisanie domy(cid:258)lnego routingu zgodnego z REST utworzonego przez wbudowan(cid:200) metod(cid:218) app.UseMvc(). Dodawanie nowych (cid:258)cie(cid:285)ek Powró(cid:202)my do kontrolera QuizController. Skoro znasz ju(cid:285) ró(cid:285)ne wzorce routingu, wykorzystamy je do zaimplementowania brakuj(cid:200)cych wywo(cid:239)a(cid:241) API. Otwórz plik QuizController.cs i dodaj poni(cid:285)szy kod (nowe fragmenty s(cid:200) pogrubione): using System; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using TestMakerFreeWebApp.ViewModels; using System.Collections.Generic; using System.Linq; namespace TestMakerFreeWebApp.Controllers { [Route( api/[controller] )] public class QuizController : Controller { 99 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera #region Metody dostosowuj(cid:200)ce do konwencji REST /// summary /// GET: api/quiz/{}id /// Pobiera quiz o podanym {id} /// /summary /// param name= id Identyfikator istniej(cid:261)cego quizu /param /// returns Quiz o podanym {id} /returns [HttpGet( {id} )] public IActionResult Get(int id) { // Tworzy przyk(cid:225)adowy quiz pasuj(cid:261)cy do (cid:298)(cid:261)dania var v = new QuizViewModel() { Id = id, Title = String.Format( Przyk(cid:239)adowy quiz o identyfikatorze {0} , id), Description = To nie jest prawdziwy quiz - to tylko przyk(cid:239)ad! , CreatedDate = DateTime.Now, LastModifiedDate = DateTime.Now }; // Przeka(cid:298) wyniki w formacie JSON return new JsonResult( v, new JsonSerializerSettings() { Formatting = Formatting.Indented }); } #endregion #region Metody routingu bazuj(cid:200)ce na atrybutach /// summary /// GET: api/quiz/latest /// Pobiera {num} najnowszych quizów /// /summary /// param name= num liczba quizów do pobrania /param /// returns {num} najnowszych quizów /returns [HttpGet( Latest/{num?} )] public IActionResult Latest(int num = 10) { var sampleQuizzes = new List QuizViewModel (); // Dodaj pierwszy przyk(cid:225)adowy quiz sampleQuizzes.Add(new QuizViewModel() { Id = 1, Title = Któr(cid:200) postaci(cid:200) z Shingeki No Kyojin (Atak tytanów) jeste(cid:258)? , Description = Test osobowo(cid:258)ci bazuj(cid:200)cy na anime , CreatedDate = DateTime.Now, 100 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Cz(cid:266)(cid:286)(cid:252) serwerowa wykorzystuj(cid:261)ca .NET Core LastModifiedDate = DateTime.Now }); // Dodaj kilka nast(cid:266)pnych przyk(cid:225)adowych quizów for (int i = 2; i = num; i++) { sampleQuizzes.Add(new QuizViewModel() { Id = i, Title = String.Format( Przyk(cid:239)adowy quiz {0} , i), Description = To jest przyk(cid:239)adowy quiz , CreatedDate = DateTime.Now, LastModifiedDate = DateTime.Now }); } // Przeka(cid:298) wyniki w formacie JSON return new JsonResult( sampleQuizzes, new JsonSerializerSettings() { Formatting = Formatting.Indented }); } /// summary /// GET: api/quiz/ByTitle /// Pobiera {num} quizów posortowanych po tytule (od A do Z) /// /summary /// param name= num liczba quizów do pobrania /param /// returns {num} quizów posortowanych po tytule /returns [HttpGet( ByTitle/{num:int?} )] public IActionResult ByTitle(int num = 10) { var sampleQuizzes = ((JsonResult)Latest(num)).Value as List QuizViewModel ; return new JsonResult( sampleQuizzes.OrderBy(t = t.Title), new JsonSerializerSettings() { Formatting = Formatting.Indented }); } /// summary /// GET: api/quiz/mostViewed /// Pobiera {num} losowych quizów /// /summary 101 Poleć książkęKup książkę ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera /// param name= num liczba quizów do pobrania /param /// returns {num} losowych quizów /returns [HttpGet( Random/{num:int?} )] public IActionResult Random(int num = 10) { var sampleQuizzes = ((JsonResult)Latest(num)).Value as List QuizViewModel ; return new JsonResult( sampleQuizzes.OrderBy(t = Guid.NewGuid()), new JsonSerializerSettings() { Formatting = Formatting.Indented }); } #endregion } } Wprowadzili(cid:258)my kilka istotnych ulepsze(cid:241): (cid:81) Dodali(cid:258)my metod(cid:218) Get, która stosuje opisywan(cid:200) wcze(cid:258)niej konwencj(cid:218) zgodn(cid:200) z REST. Metody tej b(cid:218)dziemy z pewno(cid:258)ci(cid:200) potrzebowa(cid:202), aby pobiera(cid:202) konkretny quiz na podstawie jego identyfikatora. (cid:81) Ka(cid:285)
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: