Tag Archive for: asp.net core

Wprowadzenie do platformy Azure – utworzenie aplikacji ASP.NET Web API wspomaganej bazą Azure SQL Server

Tworzenie projektu ASP.NET Core 5.0 Web API 

Utworzenie nowego projektu ASP.NET Core
1. Uruchamiamy wiersz poleceń jako administrator (command prompt wywoływany za pomocą polecenia cmd):

Command Prompt

2. Tworzymy nowy projekt ASP.NET Core Web API. W tym celu w wierszu poleceń wpisujemy  poniższe polecenie i klikamy przycisk Enter. Polecenie to utworzy nam nowy projekt o nazwie BlueYonder.Flights na dysku w folderze Azure:

 dotnet new webapi --name BlueYonder.Flights --output C:\Azure\BlueYonder.Flights

Command prompt

3. Jak już projekt zostanie utworzony, zmieniamy domyślny folder wiersza poleceń na nasz folder z projektem za pomocą następującego polecenia:

cd C:\Azure\BlueYonder.Flights

Zmiana ścieżki

Utworzenie modelu Entity Framework Core
1. Abyśmy mogli używać Entity Framework Core w naszym projekcie, potrzebujemy zainstalować odpowiedni pakiet przy użyciu poniższego polecenia:

dotnet add package Microsoft.EntityFrameworkCore.SqlServer

Dodanie biblioteki SQLServer

2. Aby przywrócić wszystkie pakiety i biblioteki, wymagane w naszym projekcie, uruchamiamy poniższe polecenie z poziomu wiersza poleceń:

dotnet restore

dotnet restore
3. Aby otworzyć naszą aplikację w Visual Studio Code, w wierszu poleceń wpisujemy poniższe polecenie:

code .

4. Folder z naszym projektem BlueYonder.Flights został otwarty w Visual Studio Code:

    • Klikamy Yes przy wiadomości Required assets to build and debug are missing from 'BlueYonder.Flights’.Add them?. Pozwoli to na zbudowanie (ang. build) naszego projektu i sprawdzenie, czy nie ma błędów w kodzie.
    • Jeśli pojawi się informacja There are unresolved dependencies, klikamy opcję Restore:

Visual Studio Code

5. Prawym przyciskiem myszy klikamy wewnątrz panelu File Explorer po lewej stronie i wybieramy opcję New Folder, a następnie nazywamy go Models:

 

dotnet restore

6. Prawym przyciskiem myszy klikamy na folderze Models, wybieramy opcję New C# Class i nazywamy ją Flight.cs. Opcja New C# Class jest dostępna dzięki rozszerzeniu do VS Code „C# Extensions”, autor: jchannon:
Utworzenie klasy Flight

7. Na górze klasy dodajemy następującą przestrzeń (ang. namespace):

using System;

Dodanie przestrzeni

8. Aby nasz model spełniał swoje zadanie, dodajemy następujące właściwości do klasy Flight:

public int Id { get ;set; }
public string Origin { get; set; }
public string Destination { get; set; }
public string FlightNumber { get; set; }
public DateTime DepartureTime { get; set; }

Dodanie właściwości do klasy
Stworzenie klasy DbContext
1. Prawym klikamy folder Models, wybieramy opcję New C# Class, a potem nazywamy ją FlightsContext.cs:
Ddoanie klasy FlightsContext
2. Na górze pliku FlightsContext.cs dodajemy następującą przestrzeń:

using Microsoft.EntityFrameworkCore;

Dodanie przestrzeni nazw
3. Nasza klasa FlightsContext będzie dziedziczyła z klasy DbContext, więc po nazwie klasy dodajemy takie dziedziczenie:

public class FlightsContext : DbContext

Dodanie DbContext
4. Wewnątrz klasy dodajemy konstruktor i właściwość Flights, która będzie zapewniała nam dostęp do naszych danych, przy użyciu następującego kodu:

public FlightsContext(DbContextOptions<FlightsContext> options) : base(options)
{
}
public DbSet<Flight> Flights { get; set; }

Dodanie konstruktora

5. Przechodzimy do klasy Startup.cs i dodajemy następujące przestrzenie:

using BlueYonder.Flights.Models;
using Microsoft.EntityFrameworkCore;

Dodanie przestrzeni

6. W metodzie ConfigureServices dodajemy połączenie (ang. connection string) do bazy danych Microsoft SQL Server, którą zaraz utworzymy w chmurze Azure:

services.AddDbContext<FlightsContext>(opt =>
opt.UseSqlServer(Configuration.GetConnectionString("defaultConnection")));

Dodanie connection string
Stworzenie kontrolera dla Web API
1. Prawym przyciskiem myszy klikamy na folderze Controllers i wybieramy opcję New C# Class. Nazywamy naszą klasę FlightsController.cs:
Dodanie kontrolera
2. Dodajemy referencję do folderu Models:

using BlueYonder.Flights.Models;

Dodanie przestrzeni
3. Dodajemy pole prywatne _context :

private readonly FlightsContext _context;

Dodanie pola _context
4. Aby wstrzyknąć kontekst bazy danych do kontrolera (inaczej mówiąc pozwolić na to, aby metody z naszego kontrolera mogły używać naszej bazy danych i operować na danych), używamy do tego konstruktora jak poniżej:

public FlightsController(FlightsContext context)
{
   _context = context;
}

Dodanie konstruktora
Stworzenie akcji i użycie kontekstu Entity Framework Core
1. Aby pobrać listę wszystkich lotów, dodajemy metodę Get, w której użyjemy pola  _context, dzięki któremu połączymy się do naszej bazy danych i z tabeli dbo.Flights pobierzemy wszystkie loty i zwrócimy je w postaci listy:

// GET api/flights
[HttpGet]
public IEnumerable<Flight> Get()
{
    return _context.Flights.ToList();
}

Dodanie metody Get
2. Do kontrolera dodajemy 3 nowe przestrzenie nazw (ang. namespaces):

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;

Dodanie przestrzeni
3. Aby dodać nowy przelot i zapisać go w bazie danych, dodajemy metodę Post, która w parametrze flight będzie przekazywała właściwości z modelu Flight, a następnie dodawała ten nowy lot do innych lotów. Następnie zapisujemy lot do bazy danych, za pomocą metody SaveChanges wracamy do akcji Get, która ma wyświetlić nam dodany właśnie przelot:

// POST api/flights
[HttpPost]
public IActionResult Post([FromBody]Flight flight)
{
    _context.Flights.Add(flight);
    _context.SaveChanges();
    return CreatedAtAction(nameof(Get), flight.Id);
}

Dodanie metody Post
4. Nad klasą kontrolera dodajemy atrybut [Route(„api/[controller]”)] oraz dodajemy dziedziczenie z klasy ControllerBase, aby wskazać, że to jest API controller:

public class FlightsController : ControllerBase

Dodanie atrybutu API

Wdrożenie aplikacji na platformę Azure

Stworzenie Azure Web App i bazy danych Azure SQL Server
1. Otwieramy przeglądarkę.
2 Przechodzimy do adresu https://portal.azure.com.
3. Jeśli strona poprosi o dane do logowania, wpisujemy adres email, klikamy przycisk Next (Następny), wpisujemy hasło, a potem klikamy przyciskSign In (Zaloguj się).
4. Jeśli pojawi się okno z pytaniem Stay signed in?, klikamy Yes:
Logowanie do Azure'a
Uwaga: Jeśli podczas procesu logowania zostanie wyświetlona strona z monitem o wybranie konta z listy wcześniej używanych kont, wybieramy konto, z którego wcześniej korzystaliśmy, a następnie kontynuujemy podawanie swoich poświadczeń.
Dodawanie poświadczeń
5. Aby wyświetlić wszystkie zasoby na Azurze, klikamy przycisk +Create a resource:
Tworzenie zasobu
6. Aby wybrać szablon dla app service, w oknie Create a resource, w polu wyszukiwania wpisujemy Web App + SQL i wybieramy z podpowiedzi szablon Web App + SQL:
Tworzenie app service
7. W oknie Web App + SQL, klikamy przycisk Create:
Tworzenie app service
8. W oknie WebApp + SQL wypełniamy następujące pola:

  • W polu App Name, wpisujemy nazwę blueyonderflightsbz:

Uwaga: Nazwa App Name będzie częścią URL i będzie obsługiwana przez domenę azurewebsites.net. Nazwa naszej aplikacji musi być unikalna w obrębie domeny. Możemy także skonfigurować na Azurze ustawienia dla naszej własnej domeny i wtedy nazwa taka musi być unikalna w obrębie naszej domeny.

  • Wybieramy subskrypcję.
  • Resource Group, klikamy link Create new, and potem wpisujemy nazwę grupy zasobów BlueYonderFlightsRG i klikamy OK:

Tworzenie app service

  • W polu App Service plan/Location klikamy znak > po prawej stronie:

Tworzenie app service

  • Klikamy przycisk + Create new:

Tworzenie app service

  • W oknie New App Service Plan w polu App Service Plan wpisujemy BlueYonderFlightsPlan, z listy rozwijanej Location wybieramy lokalizację, w której chcemy hostować naszą aplikację:

Tworzenie app service

  • Klikamy strzałkę po prawej stronie obok pozycji Pricing tier. Na stronie Spec Picker możemy wybrać parametry hostingu dla naszej aplikacji. Na zakładce Dev/Test wybieramy maszynę F1 (zapewni nam to darmowe użytkowanie aplikacji przez godzinę dziennie)  i klikamy Apply:

Wybór App Service Plan

  • W oknie New App Service Plan klikamy przycisk OK:

App Service Plan

  • Na stronie Web App + SQL klikamy znak > po prawej obok pola SQL Database:

Baza danych

  • W oknie SQL Database wpisujemy następujące informacje:
    • W polu Name wpisujemy BlueYonderFlightsDB.
    • Klikamy link Select Server poniżej Target server:

Serwer bazodanowy

  • W oknie New server wpisujemy następujące informacje:
    • W polu Server name wpisujemy blueyonderflightsserverdbbz.

Uwaga: Nazwa serwera powinna być unikalna w ramach domeny .database.windows.net.

    • W polu Server admin login wpisujemy Admin123.
    • W polach PasswordConfirm password wpisujemy silne hasło.
    • W polu Location wybieramy lokalizację, w którym chcemy hostować naszą bazę danych.
    • Klikamy przycisk Select.

Dodanie serwera bazodanowegp

  • Klikamy link Configure database pod polem Pricing tier:

Dodawanie abonamentu

  • Wybieramy opcję Serverless i klikamy przycisk Apply:

Uwaga: W opcji Serverless opłaty są naliczane co sekundę w oparciu o zużycie vCores. W opcji Provisioned opłaty są naliczane co godzinę w oparciu o wcześniej zadeklarowaną liczbę vCores i wielkość miejsca na przechowywanie danych. Możemy także wybrać inne rodzaje i wielkości baz danych, w tym bazę darmową po kliknięciu na link Looking for basic, standard, premium?:
Dodanie abonamentu
Dodawanie abonamentu

  • Klikamy przycisk Select:

Widok ustawień bazy danych

  • Klikamy przycisk Create:

Wszystkie ustawienia aplikacji i bazy danych
9. Po utworzeniu bazy danych, aby przejść do naszej bazy danych, po lewej stronie klikamy na menu, a potem wybieramy SQL Databases:
Przejście do baz danych
10. W oknie SQL databases klikamy na link prowadzący do naszej bazy danych:
Widok bazy danych
11. W oknie bazy danych klikamy na zakładce Overview klikamy przycisk Set server firewall na pasku na środku pod nazwą naszej bazy danych:
Przejście do ustawień firewalla
12. W oknie Firewall settings klikamy przycisk + Add client IP. W regułach zostaje nam dodany nasz adres IP, który pozwoli na połączenie do bazy danych. Klikamy przycisk Save, a potem przycisk Continue:
Ustawienie firewalla
13. Na samej górze klikamy link do naszej bazy danych, aby powrócić na zakładkę Overview. W panelu po lewej stronie klikamy Query editor (preview):
Ustawienia bazay danych
14. Klikamy Login, wpisujemy nasze hasło, a potem klikamy OK:
Logowanie do bazy danych
15. Aby stworzyć nową tabelę w naszej bazie, wewnątrz zakładki Query 1, wklejamy następujący skrypt i klikamy przycisk Run:

CREATE TABLE [dbo].[Flights](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Origin] [varchar](50) NOT NULL,
[Destination] [varchar](50) NOT NULL,
[FlightNumber] [varchar](50) NOT NULL,
[DepartureTime] [date] NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
));
GO

Stworzenie nowej tabeli
16. Zamykamy zakładkę Query 1 i w bazie danych sprawdzamy, czy nasza tabela jest widoczna:
Sprawdzenie, czy tabela jest widoczna
Wdrożenie  Azure Web App
1. Wracamy na stronę główną Azure Portal klikając link Home w lewym górnym rogu.
Uwaga: Jeśli pojawi się nam takie okno dialogowe klikamy przycisk OK:Powrót na stronę główną
2. Aby wyświetlić nasz App Service, klikamy menu po lewej stronie i wybieramy App Services:
Przejście do usług
3. Żeby zobaczyć konfigurację naszego w zakładce App Services klikamy link do naszej aplikacji:
Przejście do bazy danych
4. Aby dodać poświadczenia, dzięki którym będziemy mogli wdrożyć naszą aplikację do app service, pod sekscją DEPLOYMENT klikamy Deployment Center, a potem przechodzimy na zakładkę FTPS Credentials:
Dodanie poświadczeń
5. W sekcji User scope dodajemy następujące dane:

    • FTP/deployment username wpisujemy FTPBlueYonderFlightsUserBZ.
    • W polach Password i Confirm password wpisujemy złożone hasło.
    • Klikamy Save:

Dodanie szczegółów poświadczeń
Uwaga: Powyższe poświadczenia udostępniają opcje wdrażania aplikacji z wiersza polecenia.
6. W panelu po lewej stronie w sekcji Monitoring klikamy App Service Logs i zapisujemy w notatniku nazwę FTP/deployment username:
Zanotowanie poświadczeńń
7. Przełączamy się do Visual Studio Code.
8. Klikamy prawym przyciskiem myszy w panelu File Explorer po lewej stronie, wybieramy folder Properties.
9. Klikamy prawym przyciskiem myszy na folderze Properties, wybieramy New Folder i nazywamy ten folder PublishProfiles.
10. Do folderu PublishProfiles dodajemy plik Azure.pubxml:
Tworzenie Azure.pubxml
11. Wklejamy następujący kod, modyfikując odpowiednio nazwy PublishSiteName (FTP z notatnika) i Username (deployment username z notatnika) :

<Project>
<PropertyGroup>
<PublishProtocol>Kudu</PublishProtocol>
<PublishSiteName>blueyonderflights{TwojeInicjały}</PublishSiteName>
<UserName>FTPBlueYonderFlightsUser{TwojeInicjały}</UserName>
<Password>Pa55w.rd12345</Password>
</PropertyGroup>
</Project>

Dodanie zawartości do pliku Azure.pubxml
12. W wierszu poleceń wklejamy następującą komendę:

dotnet publish /p:PublishProfile=Azure /p:Configuration=Release
Publikowanie aplikacji

Uwaga: W przypadku, kiedy Publish nie przechodzi, należy zrestartować app service blueyonderflightsbz na Azurze (zakładka Overview). Po uruchomieniu możemy zobaczyć pustą tablicę jako rezultat:
Pusta tablica
Test Web API
1. Przechodzimy do portalu Azure.
2. Po lewej stronie klikamy SQL Databases.
3. Klikamy nazwę naszej bazy danych, a po przejściu do bazy danych po lewej stronie klikamy Query editor(preview).
4. Klikamy Login, a następnie wpisujemy nasze hasło.
5. W oknie klikamy +New Query i wywołujemy następujące polecenie, które stworzy nam 6 lotów:

INSERT INTO dbo.Flights(Origin, Destination, FlightNumber, DepartureTime)
VALUES('Paris', 'London', 'ABC123', '2021-06-13'),
('London', 'Warsaw', 'WEQ675', '2021-06-14'),
('Warsaw', 'New York', 'JHE543', '2021-06-15'),
('New York', 'Washington', 'CXD654', '2021-06-16'),
('Washington', 'Miami', 'MNK098', '2021-06-17'),
('Miami', 'Paris', 'DCT543', '2021-06-18');
GO

Dodanie dodanych do bazy
6. Aby pobrać wszystkie przeloty z bazy danych, wklejamy następujący skrypt do Query 1, and potem klikamy Run:

Select * from dbo.Flights;
GO
Sprawdzenie poprawności zapisania danych

7. Jeśli odświeżymy naszą aplikację, możemy zobaczyć, że aplikacja także zwraca nasze przeloty:
Sprawdzenie działania aplikacji
W ten oto sposób stworzyliśmy aplikację, za pomocą której możemy odczytać dane z bazy AzureSQL Server.
Gotowa aplikacja do pobrania z mojego Githuba.

Jak naprawić błąd 'UIFramework’ is inaccessible due to its protection level w aplikacji ASP.NET Core 3.1?

Robiąc upgrade aplikacji z .NET Core 2.2 do .NET Core 3.1, podczas przebudowywania (ang. Build Solution), aplikacja rzuciła mi błędem ”
Error CS0122 'UIFramework’ is inaccessible due to its protection level”.
Widok błędu
Jak naprawić ten błąd?
W ASP.NET Core 3.0 i wyżej przeciążenie funkcji AddIdentityUI, która pobiera parametr UIFramework, zostało usunięte. Jeśli używamy Bootstrap 4, po prostu wywołujemy AddDefaultUI().
Brak błędu

Jak naprawić błąd 'IApplicationBuilder’ does not contain a definition for 'UseDatabaseErrorPage’ w aplikacji napisanej w ASP.NET Core 3.1?

Kolejny błąd napotkany przeze mnie podczas upgrade’u aplikacji ASP.NET Core z wersji 2.2 do wersji 3.1 to błąd: „CS1061 'IApplicationBuilder’ does not contain a definition for 'UseDatabaseErrorPage’ and no accessible extension method 'UseDatabaseErrorPage’ accepting a first argument of type 'IApplicationBuilder’ could be found (are you missing a using directive or an assembly reference?).
Widok błędu
Aby naprawić ten błąd, z Nugeta doinstalowałam do projektu bibliotekę „Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore” w wersji 3.1.3. Po doinstalowaniu tej biblioteki, problematyczny błąd znika z projektu.
Dodanie biblioteki z Nuget'a
Błąd zostal naprawiony:
Widok aplikacji

Użytkownicy i role w aplikacji ASP.NET Core MVC 2.2

W ostatnim wpisie mogliśmy zobaczyć, jak dodać uwierzytelnianie do aplikacji ASP.NET Core MVC 2.2.
Dzisiaj dokonamy kolejnych modyfikacji. Stworzymy użytkowników i przypiszemy ich do odpowiednich ról, a następnie ograniczymy dostęp do określonych widoków. Projekt z kodem można pobrać z Githuba.
W przestrzeni Microsoft.AspNetCore.Identity znajduje się klasa IdentityUser,  która zawiera właściwości wykorzystywane w tabeli dbo.AspNetUsers.
Walidacja aplikacji ASP.NET Core 2.2
Teraz do folderu Data dodajemy kolejną klasę o nazwie ApplicationUser, która dziedziczy z klasy IdentityUser. Klasa ta pozwoli rozszerzyć klasę IdentityUser o właściwości, których nie ma w klasie IdentityUser.
Walidacja aplikacji ASP.NET Core 2.2
Teraz możemy przejść do klasy Startup.cs i zamienić klasę IdentityUser na ApplicationUser (linia 46).
Walidacja aplikacji ASP.NET Core 2.2
Przechodzimy do klasy ApplicationUser i dodajemy nową właściwość FirstName (będzie mi potrzebna jako kolumna w tabeli dbo.AspNetUsers).
Walidacja aplikacji ASP.NET Core 2.2
Teraz to, co musimy zrobić, to zmienić klasę IdentityUser na ApplicationUser w całym solution (rozwiązaniu).
Walidacja aplikacji ASP.NET Core 2.2
Po tej zmianie należy dodać wszędzie tam, gdzie trzeba, przestrzeń Frontend.Data.
Walidacja aplikacji ASP.NET Core 2.2
Trzeba pamiętać, żeby w plikach _LoginPartial.cshtml i _ManageNav.cshtml także zmienić klasę IdentityUser na ApplicationUser. Aby usunąć błędy należy dodać na początku tych plików następujący kod. Jest to odwołanie do projektu i folderu, w którym znajduje się klasa ApplicationUser:

@using Frontend.Data

Walidacja aplikacji ASP.NET Core 2.2
Musimy pamiętać, że sama klasa ApplicationUser powinna dziedziczyć z klasy IdentityUser, a nie z klasy ApplicationUser:

public class ApplicationUser : IdentityUser

Walidacja aplikacji ASP.NET Core 2.2
Przebudowujemy rozwiązanie (Rebuild Solution). Potem przechodzimy do SQL Server Management Studio i usuwamy bazę danych aspnet_Frontend.
Teraz z folderu Data usuwamy cały folder Migrations wraz z zawartością, gdyż za chwilę będziemy tworzyli nowe migracje. Z menu Tools wybieramy NuGet Package Manager, a nstępnie Package Manager Console i wywołujemy po kolei dwie komendy:

Add-Migration init
Update-Database

Ponieważ w naszej aplikacji są dwie klasy DbContext to musimy zmodyfikować te komendy i oprócz nazwy (ang. Name) init dodać jeszcze informację o klasie kontekstu. W przypadku tej aplikacji należy dodać: -Context ApplicationDbContext. Pierwsza komenda powinna wyglądać następująco:

Add-Migration init -Context ApplicationDbContext

Walidacja aplikacji ASP.NET Core 2.2
Teraz wywołujemy komendę, która ponownie utworzy bazę danych aspnet_Frontend i wszystkie potrzebne tabele. Tutaj w komendzie ponownie dodajemy info o kontekście.

Update-Database -Context ApplicationDbContext

Walidacja aplikacji ASP.NET Core 2.2
Kiedy przejdziemy do SSMS i do bazy danych, to możemy zobaczyć, że w tabeli dbo.AspNetUsers nie ma kolumny FirstName, którą dodaliśmy do klasy ApplicationUser.
Walidacja aplikacji ASP.NET Core 2.2
Dzieje się tak, ponieważ w klasie ApplicationDbContext nie ma połączenia z klasą ApplicationUser. Musimy tą zależność wstrzyknąć (linia 9).

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>

Walidacja aplikacji ASP.NET Core 2.2
Ponownie usuwamy bazę danych z poziomu SSMS, usuwamy folder Migrations  z naszego projektu i ponownie dodajemy migrację i aktualizujemy bazę danych:

Add-Migration init -Context ApplicationDbContext
Update-Database -Context ApplicationDbContext

Walidacja aplikacji ASP.NET Core 2.2
W ten sposób możemy dodawać potrzebne nam kolumny, których potem będziemy mogli użyć w naszej aplikacji.

Tworzenie ról niestandardowych

Aby utworzyć niestandardowe role w aplikacji, możemy utworzyć tablicę ciągów, zawierającą każdą z ról, którą zamierzamy potem wykorzystywać w naszej aplikacji, a następnie tworzymy role poprzez iterowanie elementów w naszej tablicy ciągów, przekazując każdy element do metody w klasie RoleManager. Powoduje to automatyczne utworzenie ról i ich dodanie do bazy danych.
Do klasy Startup.cs dodajemy następujący kod:

services.AddDefaultIdentity<ApplicationUser>()
               .AddDefaultUI(UIFramework.Bootstrap4)
               .AddEntityFrameworkStores<ApplicationDbContext>();
            //Info about Passwords Strength
            services.Configure<IdentityOptions>(options =>
            {
                // Password settings
                options.Password.RequireDigit = true;
                options.Password.RequiredLength = 8;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = true;
                options.Password.RequireLowercase = false;
                options.Password.RequiredUniqueChars = 6;
                // Lockout settings
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                options.Lockout.MaxFailedAccessAttempts = 10;
                options.Lockout.AllowedForNewUsers = true;
                // User settings
                options.User.RequireUniqueEmail = true;
            });
            //The Account Login page's settings
            services.ConfigureApplicationCookie(options =>
            {
                // Cookies settings
                options.Cookie.HttpOnly = true;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                options.LoginPath = "/Account/Login"; // You can type here you own LoginPath, if you don't set custom path, ASP.NET Core will default to /Account/Login
                options.LogoutPath = "/Account/Logout"; // You can type here you own LogoutPath, if you don't set custom path, ASP.NET Core will default to /Account/Logout
                options.AccessDeniedPath = "/Account/AccessDenied"; // You can type you own AccesDeniedPath, if you don't set custom path, ASP.NET Core will default to /Account/AccessDenied;
                options.SlidingExpiration = true;
            });

Walidacja aplikacji ASP.NET Core 2.2
Modyfikujemy ustawienia AddIdentity (zawartość linii 43-45 zastępujemy poniższym kodem).

   services.AddIdentity<ApplicationUser, IdentityRole>()
               .AddDefaultUI(UIFramework.Bootstrap4)
               .AddEntityFrameworkStores<ApplicationDbContext>()
               .AddDefaultTokenProviders();

Walidacja aplikacji ASP.NET Core 2.2

Rejestracja i utworzenie pierwszego użytkownika

Po wykonaniu wcześniejszych kroków nasza aplikacja umożliwia rejestrowanie się użytkowników, a także logowanie do naszego systemu po rejestracji. W kolejnych krokach dodamy autoryzację, poprzez stworzenie użytkowników i przypisanie ich do odpowiednich ról. Zanim dodamy pierwszego użytkownika, najpierw musimy przebudować i uruchomić aplikację, aby potem zarejestrować pierwszego domyślnego użytkownika, którego potem dodamy do roli Admin.
Walidacja aplikacji ASP.NET Core 2.2
Po odświeżeniu strony możemy zobaczyć, że nowo zarejestrowany użytkownik został zalogowany na naszej stronie internetowej.
W bazie danych, w tabeli dbo.AspNetUsers, mamy teraz stworzonego nowego użytkownika.

Walidacja aplikacji ASP.NET Core 2.2Utworzenie roli i przypisanie użytkownika do roli

Otwieramy plik Startup.cs i dodajemy do niego metodę CreateUserRoles w celu utworzenia nowej roli Admin, a potem przypisujemy niedawno zarejestrowanego użytkownika do roli Admin.

        private async Task CreateUserRoles(IServiceProvider serviceProvider)
        {
            // Initializing custom roles
            var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
            var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
            IdentityResult roleResult;
            // Adding Admin Role
            var roleCheck = await RoleManager.RoleExistsAsync("Admin");
            if (!roleCheck)
            {
                //Create the roles and seed them to the database
                roleResult = await RoleManager.CreateAsync(new IdentityRole("Admin"));
            }
            // Assign Admin role to newly registered user
            ApplicationUser user = await UserManager.FindByEmailAsync("testemail@gmail.com");
            var User = new ApplicationUser();
            await UserManager.AddToRoleAsync(user, "Admin");
        }

Walidacja aplikacji ASP.NET Core 2.2
W pliku Startup.cs szukamy metody Configure. Dodajemy do tej metody na samym końcu wywołanie metody CreateUserRoles (linia 119).

CreateUserRoles(services).Wait();

Walidacja aplikacji ASP.NET Core 2.2
Po ponownym uruchamieniu naszej aplikacji, możemy zobaczyć nową rolę Admin w tabeli dbo.AspNetRoles, a także widzimy, że nasz domyślny użytkownik został przypisany do roli Admin.

SELECT *
FROM aspnet_Frontend.dbo.AspNetUsers;
GO
SELECT *
FROM aspnet_Frontend.dbo.AspNetRoles;
GO
SELECT *
FROM aspnet_Frontend.dbo.AspNetUserRoles;
GO

Walidacja aplikacji ASP.NET Core 2.2

Stworzenie strony tylko dla Admina i ustawienie autoryzacji

Mamy już w aplikacji użytkownika z przypisaną rolą Admin. Teraz stworzymy dla niego stronę administracyjną, do której tylko użytkownicy z rolą Admin będą mieli dostęp.
W tym celu stworzymy nowy kontroler o nazwie Admin. Klikamy prawym przyciskiem myszy folder Controllers -> Add -> Controller, wybieramy MVC Controller – Empty i klikamy Add.
Walidacja aplikacji ASP.NET Core 2.2
Wprowadzamy nazwę kontrolera: AdminController i klikamy Add.
Walidacja aplikacji ASP.NET Core 2.2
W nowo stworzonym kontrolerze klikamy prawym przyciskiem myszy na metodę Index i klikamy Add View.
Walidacja aplikacji ASP.NET Core 2.2
Klikamy przycisk Add, aby utworzyć widok.

Teraz możemy zobaczyć stworzony kontroler i widok dla użytkowników w roli Admin.
Walidacja aplikacji ASP.NET Core 2.2
Otwieramy stronę Admin / Index.cshtml, aby zmienić jej zawartość. Dodajemy do niej prosty tekst, tak jak poniżej.

@{
    ViewData["Title"] = "Strona administratora";
}
<h2>Strona administratora</h2>
<h4>Tylko administratorzy mogą przeglądać tą stronę !!!</h4>

Walidacja aplikacji ASP.NET Core 2.2
Następnie do menu dodajemy nowy element, aby wyświetlić stronę administratora. Aby utworzyć nowy element w menu, otwieramy plik _Layout.cshtml z folderu Views / Shared. Dodajemy kod jak poniżej. Przy okazji ja zmieniłam nazwy angielskie na polskie.

<li class="nav-item">
    <a class="nav-link text-dark" asp-area="" asp-controller="Admin" asp-action="Index">Strona Admina</a>
</li>

Walidacja aplikacji ASP.NET Core 2.2
Uruchamiamy aplikację. Możemy zobaczyć nowe menu. Strona Admina została utworzona i każdy użytkownik może mieć do niej dostęp. Oznacza to, że każdy może kliknąć łącze i wyświetlić zawartość tej strony.
Walidacja aplikacji ASP.NET Core 2.2
Tutaj widzimy, że możemy wyświetlić Stronę Admina bez konieczności logowania, co oznacza, że każdy może mieć do niej dostęp.

Walidacja aplikacji ASP.NET Core 2.2Dodanie autoryzacji

Stworzyliśmy Stronę Admina tylko dla użytkownika w roli Admin, a użytkownicy z innymi rolami lub niezalogowani użytkownicy nie powinni widzieć tej strony. Aby taką funkcjonalność zaimplementować, dodamy autoryzację do kontrolera Admin. Otwieramy kontroler Admin i dodajemy poniższy wiersz kodu (linia 1 i linia 8).

using Microsoft.AspNetCore.Authorizaton;
. . .
[Authorize(Roles = "Admin")]

Walidacja aplikacji ASP.NET Core 2.2
Jeśli uruchomimy naszą aplikację i klikniemy na Stronę Admina, automatycznie zostaniemy przekierowani na stronę z logowaniem.
Walidacja aplikacji ASP.NET Core 2.2
Tylko członkowie roli Admin mogą wyświetlać Stronę Admina, ponieważ ustawiliśmy autoryzację tylko dla roli Admin. Jeśli chcemy dodać więcej ról, możemy dodawać kolejne role po przecinku, tak jak w poniższym kodzie.

[Authorize(Role = „Admin, SuperAdmin, Menager”)]

Teraz zmodyfikujemy metodę CreateUserRoles i dodamy dwie dodatkowe role: Manager i User. Potem utworzymy trzech nowych użytkowników i dodamy ich do odpowiednich ról: użytkownika beata@gmail.com do roli Admin, użytkownika romek@gmail.com do roli Manager i użytkownika daria@gmail.com do roli User.

private async Task CreateUserRoles(IServiceProvider serviceProvider)
        {
            //initializing custom roles
            var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
            var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
            string[] roleNames = { "Admin", "User", "Manager" };
            IdentityResult roleResult;
            foreach (var roleName in roleNames)
            {
                var roleExist = await RoleManager.RoleExistsAsync(roleName);
                if (!roleExist)
                {
                    //create the roles and seed them to the database
                    roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
                }
            }
            ApplicationUser user = await UserManager.FindByEmailAsync("beata@gmail.com");
            if (user == null)
            {
                user = new ApplicationUser()
                {
                    UserName = "beata@gmail.com",
                    Email = "beata@gmail.com",
                };
                await UserManager.CreateAsync(user, "Pa55w.rd");
            }
            await UserManager.AddToRoleAsync(user, "Admin");
            ApplicationUser user1 = await UserManager.FindByEmailAsync("daria@gmail.com");
            if (user1 == null)
            {
                user1 = new ApplicationUser()
                {
                    UserName = "daria@gmail.com",
                    Email = "daria@gmail.com",
                };
                await UserManager.CreateAsync(user1, "Pa55w.rd");
            }
            await UserManager.AddToRoleAsync(user1, "User");
            ApplicationUser user2 = await UserManager.FindByEmailAsync("romek@gmail.com");
            if (user2 == null)
            {
                user2 = new ApplicationUser()
                {
                    UserName = "romek@gmail.com",
                    Email = "romek@gmail.com",
                };
                await UserManager.CreateAsync(user2, "Pa55w.rd");
            }
            await UserManager.AddToRoleAsync(user2, "Manager");
        }

Walidacja aplikacji ASP.NET Core 2.2
Odpytując bazę danych aspnet_Frontend możemy zobaczyć, że zostali dodani nowi użytkownicy i przypisani do odpowiednich ról.

SELECT *
FROM aspnet_Frontend.dbo.AspNetUsers;
GO
SELECT *
FROM aspnet_Frontend.dbo.AspNetRoles;
GO
SELECT *
FROM aspnet_Frontend.dbo.AspNetUserRoles;
GO

Walidacja aplikacji ASP.NET Core 2.2
Możemy teraz określić, które role będą miały dostęp do określonych zasobów, używając ponownie atrybutu Authorize.
W naszej aplikacji założyłyśmy, że dostęp do zarządzania kategoriami będą mieli tylko użytkownicy należący albo do roli Admin albo do roli Manager. Aby dodać autoryzację do wszystkich metod w klasie, atrybut Authorize umieszczamy nad nazwą klasy CategoryController.

 [Authorize(Roles = "Admin, Manager")]

Walidacja aplikacji ASP.NET Core 2.2
Najpierw logujemy się na stronę https://localhost:44346/Category/Index jako użytkownik daria@gmail.com, który przynależy do roli User i zgodnie z naszym założeniem nie powinien mieć dostępu do klasy CategoryController. Po wpisaniu adresu zostajemy przekierowani do strony z logowaniem:
Walidacja aplikacji ASP.NET Core 2.2
Po zalogowaniu możemy zobaczyć informację, że użytkownik daria@gmail.com nie ma dostępu do wybranej strony.
Walidacja aplikacji ASP.NET Core 2.2
Teraz logujemy się na stronę jako użytkownik romek@gmail.com, który jest członkiem roli Manager.
Walidacja aplikacji ASP.NET Core 2.2
Po zalogowaniu widzimy , że ten użytkownik widzi zawartość strony i że nasza autoryzacja działa.
Walidacja aplikacji ASP.NET Core 2.2
Gdybyśmy jednak chcieli, aby dostęp do widoku Category / Index mieli wszyscy użytkownicy, bez konieczności logowania, musimy nad tą metodą dodać atrybut [AllowAnonymous] (linia 20).

[AllowAnonymous]

Walidacja aplikacji ASP.NET Core 2.2
Teraz, po uruchomieniu aplikacji, możemy zobaczyć zawartość strony ze wszystkimi kategoriami, bez konieczności uwierzytelniania.
Walidacja aplikacji ASP.NET Core 2.2
Kiedy jednak jako niezalogowany użytkownik klikniemy na link Edit, pojawia się strona z logowaniem, ponieważ pozostałe metody wymagają autoryzacji.
Walidacja aplikacji ASP.NET Core 2.2

Kontrola ról oparta na politykach

Zamiast używania atrybutów Authorize, możemy utworzyć odpowiednią politykę, która będzie zawierała wymagania dotyczące roli. Możemy dodawać i rejestrować polityki dodając je do metody ConfigureServices w pliku Startup.cs.
Do metody  ConfigureServices dodajemy następujący fragment kodu, który utworzy politykę, która umożliwi dostęp do wybranych zasobów tylko użytkownikom, którzy są członkami roli Admin.

 services.AddAuthorization(options =>
            {
                options.AddPolicy("OnlyForAdminAccess", policy => policy.RequireRole("Admin"));
            });

Walidacja aplikacji ASP.NET Core 2.2
Tak jak wcześciej, chcemy, aby dostęp do kontrolera Location mieli tylko użytkownicy, którzy mają uprawnienia Admina. Tylko widok Index będzie dostępny dla każdego. Dodajemy nad klasą LocationController atrybut Authorize wraz z odpowiednią nazwą polityki jak poniżej:

using Microsoft.AspNetCore.Authorization;
...
[Authorize(Policy = "OnlyForAdminAccess")]

Walidacja aplikacji ASP.NET Core 2.2
Kiedy uruchomimy aplikację i przejdziemy pod adres URL: https://localhost:44346/Location/Index to mamy dostęp do strony bez konieczności logowania się, ponieważ nad metodą Index umieściliśmy atrybut AllowAnonymous.
Walidacja aplikacji ASP.NET Core 2.2
Klikamy link Edit i logujemy się jako użytkownik romek@gmail.com, który należy do roli Manager.
Walidacja aplikacji ASP.NET Core 2.2
Użytkownik romek@gmail.com nie jest członkiem roli Admin, dlatego nie ma dostępu do tej strony.
Walidacja aplikacji ASP.NET Core 2.2
Kiedy jednak taką próbę podejmie użytkownik beata.zalewa@gmail.com, członek roli Admin, dostaje on dostęp do strony i może zmodyfikować dane.
Walidacja aplikacji ASP.NET Core 2.2
To co zostało na sam koniec, to wyświetlanie Strony Admina tylko dla zalogowanych członków roli Admin. W tym celu otwieramy plik _Layout.cshtml z folderu Views / Shared i edytujemy menu, tak jak poniżej. W tym kodzie najpierw sprawdzamy, czy użytkownik jest uwierzytelniony, czyli inaczej mówiąc zalogowany, a następnie sprawdzamy, czy użytkownik ma uprawnienia do przeglądania Strony Admina.

  <li class="nav-item">
      @if (User.Identity.IsAuthenticated)
      {
          @if (User.IsInRole("Admin"))
          {
              <a class="nav-link text-dark" asp-area="" asp-controller="Admin" asp-action="Index">Strona Admina</a>
          }
      }
   </li>

Walidacja aplikacji ASP.NET Core 2.2
Uruchamiamy aplikację i widzimy, że bez zalogowanego do strony użytkownika, Strona Admina nie jest wyświetlana w naszym górnym menu.
Walidacja aplikacji ASP.NET Core 2.2
Tylko zalogowany użytkownik, który jest przypisany do rol Admin widzi w menu link do Strony Admina. Możemy to zobaczyć, kiedy zalogujemy się na stronę za pomocą użytkownika w roli Admin.
Walidacja aplikacji ASP.NET Core 2.2
Potem logujemy się jako użytkownik w roli Manager i widzimy, że taki użytkownik nie widzi w menu Strony Admina i jak wcześniej sprawdzaliśmy, nie ma także dostępu do Strony Admina.
Walidacja aplikacji ASP.NET Core 2.2
Teraz możemy dodawać nowych użytkowników i nowe role oraz zarządzać dostępem do określonych widoków. Kolejnym krokiem w tworzeniu aplikacji będzie modyfikacja widoków i poprawa ich działania.

ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie

poprzednim wpisie opisałam, jak stworzyć odpowiednie kontrolery i widoki w aplikacji ASP.NET Core przy użyciu Entity Framework Core.
Teraz do aplikacji chcemy dodać autoryzację i zarezerwować wybrane akcje tylko dla określonych grup. Najpierw jednak skorygujemy pewne ustawienia w projekcie. Kiedy był tworzony projekt Frontend, wybrany został domyślny typ uwierzytelnienia dla projektu ASP.NET Core MVC, czyli No Authentication. Teraz zmienimy to uwierzytelnianie na Individual User Accounts.ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcieJeden ze sposobów na taką aktualizację możemy znaleźć w sieci. Polega on na stworzeniu w nowej lokalizacji nowego projektu o takiej samej nazwie jak nasz projekt, a następnie skopiowaniu kilku plików i folderów.
Aktualnie aplikacja jest stworzona w oparciu o szablon ASP.NET Core MVC 2.0. Najpierw więc podniesimy wersję Target Framework na ASP.NET Core 2.2 w projektach Frontend i ETBackend. Aby to zrobić klikamy prawym przyciskiem myszy na projekcie, wybieramy Properties, a potem zmieniamy Target Framework z 2.0 na 2.2. Zapisujemy zmiany.
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Następnie należy zaktualizować pakiety NuGetowe do ostatniej, stabilnej wersji. Ponieważ w projekcie Frontend mamy referencję do projektu ETBackend, to najpierw musimy zaktualizować pakiety w projekcie Frontend, a potem dopiero w ETBackend. Jeśli zmienimy kolejność to aplikacja zwróci nam komunikat z błędem, wskazujący, że próbujemy zrobić downgrade z wersji 2.2.4 do 2.0.3).
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Teraz musimy przebudować projekt. Może się okazać, że naszym oczom ukaże się taki oto nieoczekiwany błąd:
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
U mnie taki błąd wystąpił, ponieważ pakiety zaktualizowałam do wersji 2.2.4, a na systemie (Windows 10) wciąż mam wersję SDK 2.2.105. Aby naprawić ten błąd, musimy przejść na tą stronę, pobrać i zainstalować aktualne SDK (w chwili pisania tego posta aktualna wersja SDK dla pakietów 2.2.4 to 2.2.203).
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Teraz należy przebudować rozwiązanie, aby sprawdzić, czy wszystko działa jak należy. Kolejny krok to przeniesienie plików i folderów. Stworzyłam nowy projekt ASP.NET Core MVC 2.2 (z taką samą nazwą projektu i rozwiązania, jak w modyfikowanym projekcie, ale w innej lokalizacji), ale tym razem z uwierzytelnianiem Individual User Accounts. Po lewej stronie widoczne są pliki, jakie są obecnie w projekcie Frontend z uwierzytelnianiem No Authentication, a po prawej stronie nowy projekt z uwierzytelnianiem Individual User Accounts.
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Kopiujemy wybrane foldery i pliki z nowo stworzonego projektu do projektu z uwierzytelnianiem No Authentication.
Do projektu Frontend kopiujemy:

  • Folder \Areas\
  • Z pliku \Controllers\HomeController.cs metody akcji Privacy i Error
  • Plik \Views\Home\Index.cshtml
  • Folder \Data\
  • Plik \Views\Home\Privacy.cshtml
  • Plik \Views\Shared\ _CookieConsentPartial.cshtml
  • Plik \Views\Shared\ _Layout.cshtml
  • Plik \Views\Shared\ _LoginPartial.cshtml
  • Folder wwwroot
  • Plik appsettings.json
  • Kod z pliku Startup.cs, którego nie ma w starym projekcie (najlepiej różnice porównać w programie typu Notepad++).

Usuwamy dodatkowo kontroler Account i cały folder Account z folderu Views.
Kod pliku Startup.cs w moim projekcie wygląda następująco:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using ETBackend.Models;
using Microsoft.AspNetCore.Http;
using Frontend.Data;
using Microsoft.AspNetCore.Mvc;
namespace Frontend
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
var connection = @"Server=ZALNET-PC\SQLCOURSE2017; Database=ETDatabase; Trusted_Connection=True;ConnectRetryCount=0";
services.AddDbContext<ETDatabaseContext>(options => options.UseSqlServer(connection));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}

Po tych zmianach uruchamiamy projekt i poprawiamy ewentualne błędy. Ponownie uruchamiamy projekt i sprawdzamy, czy wszystko działa poprawnie.
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Jak widać na obrazku powyżej, aplikacja ma nowy wygląd, a dodatkowo nowy typ uwierzytelniania.

Dodanie autoryzacji do aplikacji ASP.NET Core

poprzednim wpisie opisałam, jak stworzyć odpowiednie kontrolery i widoki w aplikacji ASP.NET Core przy użyciu Entity Framework Core.
Teraz do aplikacji dodamy autoryzację.
W pliku appsettings.json widzimy następujące ustawienia:
Dodanie autoryzacji do aplikacji ASP.NET Core
Zmieniamy nazwę serwera z (localdb)\mssqllocaldb na nazwę własnego serwera (np. ZALNET-PC\SQLCOURSE2017) oraz skracamy nazwę bazy danych na aspnet_Frontend.
SQL Server od wersji 2012 został wyposażony w nową funkcjonalność – SQL Express LocalDb. Celem LocalDb jest zapewnienie programistom lokalnego środowiska, które jest znacznie łatwiejsze do zainstalowania i zarządzania. Zamiast instalować usługę i konfigurować zabezpieczenia, po prostu uruchamiają instancję tego nowego środowiska lokalnego LocalDb, kiedy tego potrzebują. Ponadto pobieranie instalki Express LocalDB to tylko około 33 MB (lub 27 MB, jeśli nadal korzystamy z  architektury x86), w porównaniu do 100 s MB wymaganych do pobrania pełnej wersji SQL Server Express. Ja mimo tych wszytskich zalet LocalDb wolę jednak zainstalowane wersje SQL Server.
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Na serwerze SQL tworzymy bazę danych o nazwie aspnet_Frontend, tak jak zadeklarowaliśmy to w DefaultConnection.
CREATE DATABASE aspnet_Frontend;
GO

Teraz przechodzimy do Package Manager Console i tam wywołujemy polecenie: Update-Database -Context ApplicationDbContext.
Polecenie to stworzy w naszej bazie danych wszystkie tabele, do których odwołujemy się w ApplicationDbContext.
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Po wykonaniu powyższego polecenia możemy zobaczyć, że w naszej bazie danych pojawiły się odpowiednie tabele:
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie

Testy widoków Register i Login

Uruchamiamy aplikację i rejestrujemy nowego użytkownika.
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Sprawdzamy, czy jesteśmy poprawnie zalogowani.
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Sprawdzamy, czy możemy się wylogować z aplikacji, a następnie ponownie logujemy się do aplikacji.
ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Teraz przechodzimy do bazy danych i sprawdzamy zawartość tabeli dbo.AspNetUsers:ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Jak uruchomimy aplikację, możemy zaobserwować, że gdy klikniemy na link Register, to przekierowuje nas do widoku Register i kontrolera Account w folderze Identity. Folder Identity znajduje się w folderze Areas. Ale jego aktualna zawartość to tylko folder Pages i plik _ViewStart.cshtml. Nie ma żadnych innych folderów i plików.
Dodanie Entity Framework Core do ASP.NET Core
Ale jak przejdziemy na stronę rejestracji, to widzimy, że wszystko działa i że w URL zawiera i nazwę kontrolera i nazwę metody akcji .

ASP.NET Core MVC: Zmiana ustawień z “No Authentication” na “Individual User Accounts” w istniejącym projekcie
Ale jak to wszystko działa i dlaczego? Aby zobaczyć w strukturze naszego projektu wykorzystywane tutaj widoki i kontrolery, klikamy prawym przyciskiem myszy na folderze Identity, potem klikamy Add, a potem New Scaffolded Item ….
Dodanie Entity Framework Core do ASP.NET Core

W oknie dialogowym Add Scaffold po lewej stronie wybieramy Identity i klikamy przycisk Add.
Dodanie Entity Framework Core do ASP.NET Core
W oknie dialogowym Add Identity możemy dodać wszystkie lub wybrane widoki powiązane z kontrolerem Account.
Dodanie Entity Framework Core do ASP.NET Core
Jak widać, do projektu zostały dodane nowe widoki.
Dodanie Entity Framework Core do ASP.NET Core
Teraz uruchamiamy aplikację, aby sprawdzić, czy wszystko działa tak jak trzeba. Klikamy na link Register i dodajemy nowe konto.
Dodanie Entity Framework Core do ASP.NET Core
Sprawdzamy, czy konto zostało prawidłow dodane do bazy danych.
Dodanie Entity Framework Core do ASP.NET Core

Jak to wszystko działa?

Usługi są dodawane do ConfigureServices. Typowy wzorzec to wywołanie metody Add{Service}, a potem wywołanie wszystkich metod services.Configure{Service}. Identity jest konfigurowane z domyślnymi wartościami. Usługi są dostępne dla aplikacji poprzez  dependency injection. Identity jest włączone poprzez wywołanie UseAuthentication.

Jak działają poszczególne metody możemy przeczytać na tej stronie.

Dodanie Entity Framework Core do projektu ASP.NET Core MVC

W ramach programu mentoringowego (organizowanego przez Tech Leaders Poland) razem z Michaliną tworzymy aplikację w ASP.NET Core, która w założeniu ma być portalem ogłoszeniowym. Projekt został stworzony w ASP.NET Core 2.0 i cały czas jest modyfikowany.
Diagram bazy danych, utworzonej podczas naszych spotkań, wygląda tak jak na rysunku poniżej.  Jak stworzyć wykorzystywaną tutaj bazę danych opisałam w tym wpisie.
Dodanie Entity Framework Core do ASP.NET Core
Obecnie w rozwiązaniu ET mamy 2 projekty i pliki:

  • projekt ze skryptem bazy danych ET (opis, jak go stworzyć dodałam na blogu)
  • projekt Frontend (ASP.NET Core MVC 2.0)

Dodanie Entity Framework Core do ASP.NET Core
Aby ułatwić i przyspieszyć proces tworzenia aplikacji, możemy przy użyciu naszej bazy danych i Entity Framework Core, wygenerować wszystkie potrzebne nam encje.  Najpierw musimy zainstalować pakiet EF Core dla wybranego przez nas dostawcy bazodanowego. W tym projekcie korzystamy z bazy Microsoft SQL Server 2017.
Aby w przyszłości łatwiej można było zarządzać projektem, przeniesiemy folder Models do nowego projektu i tam dodamy Entity Framework Core. W tym celu w Visual Studio 2017 (lub Visual Studio 2019) klikamy prawym przyciskiem myszy na Solution i wybieramy opcję Add -> New Project ->.NET Core ->Class Library (.NET Core). Zarówno nowy projekt, jak i projekt Frontend mają jako Target Framework wersję .NET Core 2.0.
Dodanie Entity Framework Core do ASP.NET Core
Do projektu Frontend dodajemy referencję do projektu ETBackend. W projekcie Frontend klikamy prawym przyciskiem myszy na Dependencies, potem wybieramy Add Reference … i w oknie dialogowym Reference Manager – Frontend zaznaczamy pole wyboru obok projektu ETBackend i klikamy przycisk OK.
Dodanie Entity Framework Core do ASP.NET Core
W nowo utworzonym projekcie tworzymy folder Models (prawym klikamy na projekcie ETBackend, potem wybieramy Add -> New Folder i zmieniamy nazwę na Models). Z folderu Models w projekcie Frontend wycinamy plik ErrorViewModel.cs i wklejamy go do folderu Models w projekcie ETBackend. Po przeniesieniu pliku ErrorViewModel.cs zmieniamy w nim namespace z Frontend.Models na ETBackend.Models. Przebudowujemy całe rozwiązanie (z menu Build wybieramy opcję Rebuild Solution), poprawiamy ewentualne błędy, aż zobaczymy informację Rebuild Succeeded (na samym dole na niebieskim pasku).
Dodanie Entity Framework Core do ASP.NET CoreNastępnie z menu wybieramy Tools, potem NuGet Package Manager, a następnie Package Manager Console. W oknie dialogowym Package Manager Console w Package source wybieramy All, a w Default project wskazujemy nasz projekt (ETBackend). U mnie jest to ETBackend. Uruchamiamy następujące polecenie, aby stworzyć model z istniejącej bazy danych ETDatabase. Polecenie to wygeneruje dla każdej tabeli znajdującej się w bazie danych plik w folderze Models z nazwą taką samą, jak nazwa tabeli.
Server – podajemy nazwę naszgo servera bazodanowego
Database – nazwa bazy danych
Trusted_Connection = True – gdy nasze połączenie do serwera jest oparte na Windows Authentication
Scaffold-DbContext "Server=ZALNET-PC\SQLCOURSE2017;Database=ETDatabase;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
Dodanie Entity Framework Core do ASP.NET Core

Po wykonaniu tego polecenia możemy zobaczyć, że proces reverse engineering (inżynierii odwrotnej) utworzył klasy encji (Adverts.cs, AdvertsCategories.cs, Categories.cs, Locations.cs i Users.cs) oraz klasę derived context (ETDatabaseContext.cs) w oparciu o schemat istniejącej bazy danych. Możemy też określić, dla których wybranych tabel chcemy wygenerować klasy, dodając argument -Tables do powyższego polecenia, np. -Tables Adverts, Categories.
Dodanie Entity Framework Core do ASP.NET Core

Aby usunąć widoczne na screenie błędy, należy dodać referencję do trzech pakietów NuGet. Aby to zrobić, klikamy prawym przyciskiem myszy na projekcie ETBackend i wybieramy Manage NuGet Packages. Następnie dodajemy pakiety: Microsoft.EntityFrameworkCore (2.0.3)Microsoft.EntityFrameworkCore.Design (2.0.3)Microsoft.EntityFrameworkCore.SqlServer (2.0.3).
Dodanie Entity Framework Core do ASP.NET Core
Klasa context reprezentuje połączenie z bazą danych i pozwala na wykonywanie zapytań do bazy danych i zapisywanie instancji klas encji (poniżej fragment kodu).
Dodanie Entity Framework Core do ASP.NET Core
Kolejny krok to rejestracja kontekstu (ETDatabaseContext.cs) z dependency injection. Koncepcja wstrzykiwania zależności (dependency injection) jest kluczowa dla ASP.NET Core. Usługi (services), takie jak w ETDatabaseContext, są rejestrowane z dependency injection podczas uruchamiania aplikacji. Komponenty, które wymagają tych usług (takie jak kontrolery MVC), są następnie dostarczane tym usługom za pośrednictwem parametrów lub właściwości konstruktora.
Kolejny krok w tworzeniu naszej aplikacji to rejestracja i konfiguracja naszego kontekstu(context) w klasie Startup.cs w projekcie Frontend. Robimy to, aby ETDatabaseContext był dostępny dla kontrolerów MVC oraz rejestracji kontekstu jako usługi. Aby to zrobić otwieramy plik Startup.cs i dodajemy następujące instrukcje using na początku pliku:
using ETBackend.Models;
using Microsoft.EntityFrameworkCore;

Teraz przy użyciu metody AddDbContext(…) rejestrujemy kontekst jako usługę. W pliku Startup.cs lokalizujemy metodę ConfigureServices(…) i dodajemy poniższy kod, aby zarejestrować kontekst jako usługę.
Dodanie Entity Framework Core do ASP.NET Core
Aktualnie połączenie do bazy danych, czyli connection string, znajduje się w pliku Startup.cs. Nie jest to jednak najlepsze rozwiązanie w środowiskach produkcyjnych i dlatego w późniejszym czasie, aby zapewnić większe bezpieczeństwo aplikacji, to połączenie dodamy do pliku konfiguracyjnego.
Jak po przebudowaniu rozwiązania dalej będą jakieś błędy, to może być konieczne dodanie do projektu Frontend 2 dodatkowe pakiety NuGet: Microsoft.EntityFrameworkCore (2.0.3)Microsoft.EntityFrameworkCore.Design (2.0.3).
Dodanie Entity Framework Core do ASP.NET Core
Teraz, jak mamy już zarejestrowany kontekst, możemy dodać kontrolery i widoki.
Najpierw musimy przebudować całe rozwiązanie (Rebuild Solution). W innym przypadku nasze klasy z folderu Models będą niewidoczne dla kontrolerów. Prawym przyciskiem myszy klikamy na folderze Controllers w Solution Explorer i wybieramy opcję Add -> Controller… .Z dostępnych opcji wybieramy MVC Controller with views, using Entity Framework i klikamy OK. Model class wybieramy: Adverts(ETBackend.Models), a w Data context class wybieramy: ETDatabaseContext(ETBackend.Models).Podajemy nazwę kontrolera (liczba pojedyncza) i do nazwy obowiązkowo dodajemy słowo Controller (po tym słowie są rozpoznawane klasy kontrolera). Klikamy przycisk Add.
Dodanie Entity Framework Core do ASP.NET Core
Po wykonaniu wszystkich tych czynności mamy nowy kontroler z automatycznie utworzonymi akcjami do przeglądania, tworzenia, edycji i usuwania ogłoszeń, a także nowe widoki do wyświetlania tych informacji. Wykonujemy te same czynności dla pozostałych klas z folderu Models.
Dodanie Entity Framework Core do ASP.NET Core
Jeśli wszystko poszło tak jak trzeba, możemy uruchomić naszą aplikację i sprawdzić rezultaty. W menu przechodzimy do sekcji Debug, a potem wybieramy Start Without Debugging. Aplikacja uruchomi się w nowym oknie przeglądarki. Możemy przejść do jakiegokolwiek kontrolera i sprawdzić działanie strony.
Dodanie Entity Framework Core do ASP.NET Core
Otrzymaliśmy aplikację z podstawowymi metodami, za pomocą których możemy manipulować danymi i zapisywać je w bazie danych.