ASP.NET CoreCzęść NR.1 ASP.NET Core jest to nowy framework Microsoftu, który został zbudowany na nowo. Dlaczego został zbudowany na nowo? By był szybszy, bardziej elastyczny, nowoczesny i żeby działał na różnych platformach jak LINUX i OS X.

Skończyły się więc wymówki, by nie pisać w ASP.NET bo nie można tego uruchomić na Linux. ASP.NET Core jest frameworkiem z platformy .NET i będziesz go używał do tworzenia stron.

W tym kursie zbudujemy stronę internetową zaczynając od pustego projektu. W taki sposób, abym mógł  ci pokazać jak te wszystkie elementy ze sobą się łączą.

Zainstalujemy odpowiednie poboczne rozwiązania. Potem przyjrzymy się frameworkowi MVC.

W MVC na szczęście dużo się nie zmieniło. Jeśli znasz MVC, to nie musisz się uczyć wszystkiego od nowa. Mamy wciąż widoki, kontrolery, modele. Oczywiście doszło dużo nowych rzeczy jak:

  • TagHelpers
  • View Compoments
  • Dependency Injection

Skoro budujemy stronę internetową, to nie będziemy mogli obejść się bez jakiegoś źródła danych. Skorzystamy więc z SQL Servera by utworzyć bazę.

Aby być najbardziej na czasie do komunikacji z bazą danych w SQL Serverze użyjemy najnowszego frameworka ADO.NET Enity Framework 7  .

Na każdej stronie są formularze i użytkownicy. Stare rozwiązania znane z ASP.NET jak MembershipProvider odchodzą w niepamięć, dlatego w tym kursie przyjrzymy się rozwiązaniu Identity, które istnieje już od jakiegoś czasu.

Mimo, iż najbardziej chcę się skoncentrować na rozwiązania backend, to jednak trzeba także spojrzeć na to, jak nasza strona będzie wyglądać z punktu widzenia użytkownika w jego przeglądarce. 

Nowoczesna strona internetowa nie może się obejść bez bibliotek CSS i JavaScript. O jakich bibliotekach mówimy?- oczywiście o Bootstrap i jQuery.

Po tym kursie zapoznasz się z ASP.NET Core i będziesz mógł tworzyć w nim strony internetowe. Na tym etapie spodziewam się, że znasz C# i masz podstawową wiedzę na temat HTML i pojęcia jak CSS i JavaScript nie wydają ci się obce.

Jeśli nie znasz C#, to mogę ciebie odesłać do moich dwóch kursów, które napisałem dawno temu.

Co jest potrzebne

Do pracy będzie ci potrzebne Visual Studio 2015. Ja korzystam z wersji Enterprise, ale będę szczery, tobie wystarczy wersja darmowa Community.

Tak, mroczne czasy Visual Web Developera już dawno minęły.

Visual Studio 2015

Po zainstalowaniu Visual Studio Community Edition 2015 bądź innej płatnej wersji Visual Studio.

Potem będziesz musiał zainstalować najnowszą wersję narzędzi ASP.NET and Web Tools. Jak widzisz ja obecnie korzystam z wersji RC, ale zapewne, gdy czytasz ten kurs istnieje już pełna wersja.

Jak więc pobrać najnowszą wersję narzędzi ASP.NET?

Czy wiedziałeś, że istnieje dokumentacja ASP.NET, a w niej znajdują się odpowiednie instrukcje jak zainstalować ASP.NET dla każdej platformy.

Dokumentacja ASP.NET CORE

Jak będziesz pisał aplikacje na systemie operacyjnym Windows. Kto wie być może w przyszłości Visual Studio będzie miało wbudowaną instalację najnowszego ASP.NET, na razie warto przeczytać instrukcję jak i co trzeba zainstalować.

Instalacja ASP.NET Core

Z punktu widzenia użytkownika windows instalacja jest prosta. Instalujesz Visual Studio i pilnujesz aby zaznaczyć opcję “Microsoft Web Developer Tools”. Potem instalujesz ASP.NET klikając na link ASP.NET 5.

Niech nazwa ASP.NET 5 ciebie nie myli bo to już niedługo się zmieni. W tym momencie jednak, gdy to piszę nie wszystkie źródła Microsoftu zmieniły nazwę z ASP.NET 5 na ASP.NET Core.

asp.net 5 a asp.net core

Dlaczego nazwa się zmieniła? Powiedzmy, że nazwa ASP.NET 5 oznaczałaby wsteczną kompatybilność z ASP.NET 4, co nie byłoby prawdą.

Frameworku ASP.NET Core stawia zupełnie nowe kroki i jest w środku zupełnie inaczej zbudowany. To jest właśnie główny powód dlaczego postanowili go nazwać  inaczej.

Gdy już wszystko zainstalowałeś przejdźmy do utworzenia pierwszego projektu.

Nowy projekt ASP.NET i twoja pierwsza strona

Wewnątrz Visual Studio chce utworzyć aplikację.

Z menu głównego wybieram więc File –> New –> Project.

Nowy projekt Visual Studio

W oknie New Project w zakładce Visual C# zaznaczam “Web”. W drugim oknie ze wszystkich szablonów WEB wybieram ASP.NET Web Appliaction.

ASP.NET Web Application

Swój projekt nazwałem “GamerPoems”. Tak utworzę stronę z poematami dla graczy, pisanymi przez graczy. W polu tekstowym Location jest określone miejsce, w którym powstanie projekt.

Jeśli chcesz możesz go zmienić.

ASP.NET 5 Template Empty

W następnym oknie wyświetlą się szablony ASP.NET. Szablony ASP.NET 4.5.2 są szablonami poprzedniej wersji ASP.NET . To, co chcę wybrać to szablony ASP.NET 5, które zapewne później zostaną nazwane szablonami ASP.NET Core.

Wybieram szablon Empty

Mógłbym wybrać szablon “Web Application”, który już ma wszystko zainstalowane i poukładane. Jednak moim zdaniem na początek lepiej zacząć od pustego szablonu tak, by się dokładnie przyjrzeć, jak to wszystko działa krok po kroku.

Tak właśnie zrobimy.

Host in the cloud

Zanim wciśniesz przycisk OK upewnij się, że odznaczyłeś opcję “Host in the cloud”.

Welcome to ASP.NET 5

Zamknij niepotrzebne okno, które się otworzyło przy tworzeniu projektu. Obecnie nasz projekt wygląda tak. Co każda z tych części robi? Omówię za chwilę.

Soluction Explorer

Na razie uruchom ten projekt wciskając CTRL+F5 lub z wybierając z okna Debug opcję “Start Without Debugging”.

Start Debuging

Pamiętaj, że nie zainstalowaliśmy MVC więc nasza aplikacja niewiele potrafi. Obecnie nasza aplikacja ASP.NET Core potrafi robić tylko jedną rzecz.

Wyświetlić napis Hello World.

Hello World

Dlaczego wyświetla ten napis i jak? O tym za chwilę. Nasza strona działa pod adresem localhost:42200. U ciebie port zapewne będzie inny, bo jest przeznaczony losowo.

Patrząc na pasek zadań powinieneś zwrócić uwagę na ikonę pokazującą serwer IIS Express.

 IIS Express

Klikając na ikonę mogę zobaczyć nazwę swojej witryny. Jeśli programowałeś wcześniej z ASP.NET , to zapewne znasz już związek pomiędzy Visual Studio a serwerem IIS.

Istnieje, co prawda pewna różnica jak te elementy ze sobą współpracują, ale o tym później.

IIS Express 2

Serwer IIS Express hostuje lokalnie twoją stronę. Nie musisz w to na razie głębiej wchodzić.

Co w projekcie jest

A gdzie nasz projekt został utworzony? Aby to sprawdzić kliknij prawym przyciskiem myszki z menu wybierz “Open Folder in File Explorer”.

Open Folder in File Explorer

Jak widać tutaj znajduje się nasz projekt. Foldery i pliki są dokładnie takie same jak w Visual Studio.

Folder ASP.NET Core

A gdzie nasza solucja. Solucja potrafi trzymać zbiór projektów. Obecnie solucja “GamersPoems” ma tylko jeden projekt, ale nie znaczy to, że nie może mieć więcej.

Solution

Analogicznie do poprzedniego razu sprawdź, gdzie znajduje się plik solucji.

Open Folder in File Explorer

W folderze, gdzie znajduje się solucja mamy dwa pliki. Plik o rozszerzeniu “sln”  jest to plik, który otworzy Visual Studio z tą obecną solucją.

Jeśli więc zamkniesz Visual Studio to, aby otworzyć ponownie tę solucję musisz tylko kliknąć na ten plik.

Folder solucja

Drugi plik global.json zawiera informację na temat samego projektu. Po pierwsze ten plik pokazuję Visual Studio, gdzie powinien on szukać projektów tej solucji.  Jak widać wszystkie projekty tej solucji znajdują się w folderze “src”.

W folderze “test”, którego nie ma znajdowałyby się projekty testujące mój kod. Nie mam takiego projektu, więc nie ma takiego folderu.

Przy okazji ten plik informuję Visual Studio, że ta solucja korzysta z biblioteki ASP.NET Core 1.0.0-rc-update1. Dla nas jednak nie jest to istotna informacja.

global.json

A teraz czas na pewien super dodatek związany z tym, jak Visual Studio serwer IIS i aplikacja ASP.NET Core działają między sobą.

Jeśli skasujesz jakiś plik w folderze projektowym, który znajduje się w folderze src, to ten plik równocześnie zostanie skasowany z Visual Studio.

Kiedyś tak nie było. Kiedyś kasowanie plików, powiedzmy obrazków wiązało się z manualnym kasowaniem ich w oknie solucji. Teraz to już przeszłość.

Istnieje jednak coś jeszcze bardziej fantastycznego. Możesz otworzyć plik Startup.cs w notatniku lub w innym edytorze i zmienić tekst z Hello World na coś innego.

Zmiana pliku w notatniku

Co się wtedy stanie?

Kiedyś odpowiedź brzmiałaby nic. Trzeba przecież przebudować, skompilować cały projekt jeszcze raz, by ta zmiana została zarejestrowana do bibliotek, które uruchamiają kod twojej strony.

Dziś jest inaczej. Visual Studio, kompilator, serwer IIS potrafi wykryć zmianę plików nawet serwerowych i przekompilować po cichu cały projekt i natychmiast po odświeżeniu strony wyświetlić twoje wprowadzone zmiany.

image

Jest to wspaniała rzeczy. Rozumiem dlaczego to zostało wprowadzone. Visual Studio nie jest jedynym edytorem, który może pisać kod do aplikacji WEB jak ASP.NET.

Swój kod mógłbym edytować Visual Studio Code, który jest lżejszą opcja tworzenia kodu.

Visual Studio Code

Swój kod mógłbym edytować w edytorze w ogóle nie związanym z Microsoftem, jak Sublime Text.

Sublime Text

Na siłę mógłbym edytować kod w notatniku i odświeżać stronę patrząc jak moje działania są automatycznie prowadzane do przekompilowanych bibliotek.

Wydaje się, że jest to mała rzecz, ale jakby się głębiej zastanowić zmienia ona wszystko. Nie musimy edytować swojego kodu w Visual Studio.

Poject.json

Zróbmy małą turę po plikach w naszym projekcie ASP.NET. Na pierwszą linię ognia idzie  plik projekt.json. Jak widzimy jest to kolejny plik konfiguracyjny, który przechowuje informację w notacji JSON.

Ten plik jest sercem aplikacji .NET.  Bez tego pliku nie mielibyśmy tutaj projektu ASP.NET Core.

{
  "version": "1.0.0-*",
  "compilationOptions": {
    "emitEntryPoint": true
  },

  "dependencies": {
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final"
  },

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel"
  },

  "frameworks": {
    "dnx451": { },
    "dnxcore50": { }
  },

  "exclude": [
    "wwwroot",
    "node_modules"
  ],
  "publishExclude": [
    "**.user",
    "**.vspscc"
  ]
}

Na samej górze tego pliku widzimy informację określającą wersję naszego projektu, który budujemy. Ta wersja zostanie potem przypisana do biblioteki, gdy zbudujemy projekty.

"version": "1.0.0-*",

Najważniejsza część tego pliku jednak leży w polu “dependencies”.

W tym bloku pliku project.json jest określony z jakich bibliotek obecnie mój projekt korzysta.  Użycie bibliotek jest nieuniknione. Jeśli będę chciał ściągnąć informację z baz danych, to użyję do tego odpowiedniej biblioteki. Jeśli będę chciał wyświetlić stronę według zasad MVC to zainstaluję do tego odpowiednią bibliotekę.

"dependencies": {
  "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
  "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final"
},

Obecnie .NET i ASP.NET Core dąży do tego by wszystkie zależności projektowe można było pobrać z serwisu NuGet. Jest to prawdziwe stwierdzenie dla najnowszych projektów dla starszych już nie.

NuGet jest menadżerem paczek. W paczkach znajdują się biblioteki, które dodają funkcję do naszego projektu.

NuGet istnieje od wyjścia Visual Studio 2010 czyli od jakiegoś czasu. Przy pomocy menadżera NuGet pobierzemy więc później odpowiednie biblioteki i API, aby łatwiej było nam stworzyć aplikację.

NuGet

Obecnie mamy tylko dwie zależności do dwóch paczek. Te paczki zapewne się zmienią, gdy ASP.NET Core wyjdzie oficjalnie.

Jak dodać kolejne paczki? Mogę to zrobić na wiele sposobów. Mogę wpisać magiczne słowa do konsoli Nuget. Mogę też ręcznie napisać nazwę paczki w bloku dependencies.

Nie jest to jednak zalecany sposób, bo jak widzę Intellisense podpowiada mi złą wersję paczki MVC.

Uzupełnienie dependencies

Zalecanym sposobem jest skorzystanie z UI Visual Studio. Klikając prawym przyciskiem na ikonę References z menu wybierz opcję “Manage NuGet Packages…”.

ManageNuGet Packages

Ukaże ci się okno ze wszystkimi zainstalowanymi  obecnymi paczkami.

NuGet Package Window

Zmieniając jednak zakładkę na “Browse” i zaznaczając opcję “Include prerelase” mogę zobaczyć inne paczki, których jeszcze nie zainstalowałem.

Zaznaczyłem opcję “Include prerelase” ponieważ ASP.NET Core i inne biblioteki jeszcze oficjalnie nie wyszły.

NuGet Package Window Browse

Nie muszę daleko szukać by móc znaleźć paczkę “ASP.NET MVC” 6.0.0-rc1-final. Obecnie niczego jednak nie instaluję, ale zrobię to później w następnych częściach kursu.

NuGet Package Window Browse ASP.NET MVC

Następny blok frameworks pokazuje z jakich .NET frameworku mój projekt może korzystać. Jak widać mamy tutaj określone dwa frameworki .NET.

"frameworks": {
  "dnx451": { },
  "dnxcore50": { }
},

dnx451 jest to pełny framework .NET. Jest to ten framework, który się zainstalował wraz z Visual Studio. Jest to najnowszy framework dołączony z systemem operacyjnym Windows.

Jest to framework .NET, który był z nami przez 15 lat. Ten framework zawiera w sobie wszystko, co potrzebne do tworzenia oprogramowania WEB jak i oprogramowania na systemy operacyjne Windows jak np. WPF, Windows Forms.

To potężny framework, który działa tylko pod systemy operacyjny Windows.

ASP.NET CORE 1.0

DNXCore50 jest to framework .NET Core 1.0.

.NET Core 1.0 jest to framework cross platformowy, więc może on działać pod różnymi platformami jak Linux i OSX.

Ten  framework nie jest aż tak rozbudowany jak framework, który znaliśmy .NET 4.6, ale ma on wszystkie właściwości potrzebne do utworzenia aplikacji ASP.NET.

W przyszłości spodziewam się, że aplikacje ASP.NET będą celować jedynie do framework .NET Core 1.0. Nie ma sensu tworzyć dwóch bibliotek dla dwóch różnych wersji frameworka w swojej aplikacji.

Jeśli otworzysz ikonę References to zobaczysz, że twój projekt obecnie ma referencję do paczek z dwóch różnych frameworków.

References

Co ciekawe teraz można zobaczyć, jak kolejne paczki mają zależności do kolejnych paczek i tak dalej. Jest to na pewno bardziej przyjazne dla oka niż cała lista bibliotek.

References more

W pliku project.json mamy jeszcze dwa bloku kodu. Oznaczają one jednak to, co nie powinno być kompilowane i co nie powinno być wysłane na serwer w czasie publikacji strony.

Jak widać wyłączony z kompilacji jest folder wwwroot. Dlaczego?

"exclude": [
  "wwwroot",
  "node_modules"
],
"publishExclude": [
  "**.user",
  "**.vspscc"
]

wwwroot

W folderze wwwroot będą znajdować się pliki statyczne naszej strony. Będą to obrazki, pliki javascript, pliki CSS i pliki HTML.

Jeśli więc chcę mieć jakieś pliki, które mam wyświetlić pod protokołem HTTP, to one powinny być tutaj. W innych miejscach będą znajdować się pliki do obsługi kodu po stronie serwera,  czyli pliki kodu C#.

Na razie w folderze wwwroot znajduje się plik web.config, który zawiera specyficzne ustawienia dla serwera IIS, które nas nie interesują.

W następnej części kursu umieścimy prosty plik HTML w folderze wwwroot i go obsłużmy.

Startup.cs

Następnym plikiem, który warto omówić jest plik Startup.cs.

Jeśli wcześniej programowałeś w ASP.NET to odpowiedź na pytanie, czym jest ten plik jest bardzo prosta. Wcześniej w ASP.NET istniał plik Global.asax, który obsługiwał globalne zdarzenie aplikacji, jak jej uruchomienie czy wystąpienie błędów.

Teraz te funkcje zostały przeniesione do pliku Startup.cs. Moim zdaniem bardzo słusznie, bo sama nazwa jak i rozszerzenie pliku Global.asax jest bardzo nie intuicyjne. 

Startup.cs

Startup.cs robi jednak coś więcej. Wcześniej w ASP.NET wiele ustawień leżało po stronie pliku konfiguracyjnego web.config.

Zespół ASP.NET doszedł jednak to słusznego wniosku, że wiele ustawień w tym pliku nie powinno siedzieć w formie tekstu XML. Bardziej intuicyjne byłoby napisanie kodu, który robi to samo, co litry tekstu XML w tym pliku konfiguracyjnym.

Tak też się stało. Nie będę ukrywał swojego zadowolenia. To genialny pomysł.

Konfiguracja leży teraz głównie w kodzie C# i w tym pliku.

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app)
    {
        app.UseIISPlatformHandler();

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("Cez World!");
        });
    }

    // Entry point for the application.
    public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}

Wewnątrz tego pliku znajduje się klasa Startup. ASP.NET będzie szukał tej klasy według konwencji. W tej klasie są dwie metody, na których zaraz się skoncentrujemy.

W metodzie Configure jest tworzony procesor odpowiedzi strumieni HTTP. To definiuje jak moja aplikacja będzie odpowiadać na moje zapytania HTTP.

public void Configure(IApplicationBuilder app)
{
    app.UseIISPlatformHandler();

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("Cez World!");
    });
}

Na razie moja aplikacja, gdy wywołam na niej jakiekolwiek zapytanie HTTP odpowie mi tekstem “Cez World!”.

Jeśli jednak chcę, by moja aplikacja zachowała się inaczej będę musiał dokonać tutaj pewnych zmian. W następnym wpisie dodamy tutaj parę wywołań metod z innych klas.

W następnym wpisie zrobimy tutaj prostą obsługę pliku statystycznego HTML. Dodamy tutaj też stronę błędów, jeśli nasza aplikacja natrafi na wyjątek.

Mamy także metodę ConfigureServices. W tej metodzie definiujemy komponenty naszej aplikacji. ASP.NET ma wbudowaną obsługę wstrzykiwania zależności. Nie jest potrzebny nam żaden kontener, bo to już mamy w ASP.NET Core.

Jeżeli wstrzykiwanie zależności, kontenery i odwrócenie kontroli brzmi dla ciebie jak czarna magia…Nie martw się zaraz ci pokażę jakie to jest proste, bez zbędnego mambo-jambo dziwnych definicji.

public void ConfigureServices(IServiceCollection services)
{
}

Na razie powiem ci, że technika wyzyskiwania zależności pozwala nam na elastyczną zmianę zachowania pewnej części naszej aplikacji poprzez zmianę odpowiedniego komponentu

Kod w takim przypadku nie będzie bezpośrednio korzystał z danej klasy. Będzie on  prosił o dany moduł, który wykona tę porcję zadania bez wiedzy czym dokładnie ten moduł jest.

Brzmi dziwnie nieprawdaż? Dlatego zanim skończę tę część kursu zrobię szybki moduł, który zostanie obsłużony przez kontener ASP.NET Core

Wstrzykiwanie zależności

Do projektu dodaj folder “Services”.

Add new Folder

W folderze Services dodaj klasę “Messages”.

Add class

Do pliku klasy utworzyłem interfejs IMessages, który określi mi, że  komponent, który obsłuży ten interfejs na pewno będzie miał metodę Hello.

Klasa Message implementuje interfejs IMessages w związku z tym moja klasa musi obsłużyć metodę Hello.

namespace GamersPoems.Services
{
    public interface IMessages
    {
        string Hello();
    }

    public class Messages : IMessages
    {
        public string Hello()
        {
            return "Cez Hello";
        }
    }
}

Wracając do pliku Startup.cs w metodzie Configure dodaję parametr IMessages. Korzystając z pomocy Visual Studio dodaj informację o tym, że będziesz używał odpowiedniej przestrzeni nazw.

using

Metoda Configure przyjmuje interfejs IMessages jako parametr. Metoda Configure na tym etapie nie wie, czym dokładnie ten parametr będzie.

Mogę jednak wywołać metodę Hello().

public void Configure(IApplicationBuilder app, IMessages messages)
{
    app.UseIISPlatformHandler();

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync(messages.Hello());
    });
}

Jeśli teraz uruchomisz aplikację to zobaczysz, że  kod nie wie, czym dokładnie IMessages ma być. Jest to normalne zachowanie ponieważ nigdzie tego nie określiłem.

Error 500

Postaw breakpoint przy metodzie ConfigureServices i uruchom aplikację.

BreakPoint

Jak widzisz w parametrze services, w  którym są zadeklarowane wszystkie moduły nie ma naszego modułu IMessages. Natomiast jest cała lista modułów, które są obsługiwane i wstrzykiwanie przez ASP.NET domyślnie.

Liczba dodanych zależności

Dodajmy więc obsługę naszego modułu i powiedzmy czym IMessages ma być, gdy zostanie on poproszony o swoją implementacje.

AddSigleton

Możemy określić różne poziomy życia naszego modułu, ale na potrzeby tego wpisu wybiorę cykl życia typu Singleton.

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IMessages, Messages>();
}

Teraz, gdy zatwierdziłem czym IMessages ma być, kod uruchamia się bez żadnych problemów.

Działa

Na tym kończę ten wpis. Do zobaczenia w Middelware w ASP.NET Core.