Kihagyás

ASP.NET Core - Heroes alkalmazás

Projekt létrehozása

  1. Visual Studio segítségével
  2. New Project -> ASP.NET Core Web Application
  3. Válasszuk ki a Web Application (Model-View-Controller) template-et
  4. Minden más opcionális lehetőséget hagyjunk a default beállításokon (pl. no authentication)
  5. dotnet CLI-vel
  6. Nyissunk egy terminált, hozzunk létre egy új mappát a projektünknek (mkdir HeroesWeb) és lépjünk be a mappába (cd HeroesWeb)
  7. A dotnet new mvc parancs segítségével hozzuk létre az ASP.NET Core MVC Web Appunkat
  8. Nyissuk meg Visual Studio Code-ban a projektünk mappáját
#Tipp: Visual Studio Code

Amennyiben Visual Studio Code-ot használunk, a következő extension-ök lesznek a segítségünkre:

  • C# (Microsoft)
  • C# Extensions (jchannon)
  • .NET Core Tools
  • Auto-Using for C#

Adatbázis létrehozása EF Code First segítségével

A következő nuget package-(eke)t adjuk hozzá a projekthez:

  • Microsoft.EntityFrameworkCore.Sqlite (2.1.11)

#Tipp: dotnet CLi-vel pl. dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 2.1.11

Data Annotations

.NET-ben lehetőségünk van data annotations használatára (.NET 3.5-től kezdve), amikkel valamilyen extra tulajdonságot, jelentést fűzhetünk osztályokhoz, property-khez attribútumok segítségével. A használatához a System.ComponentModel.DataAnnotations namespace behúzására van szükségünk.

Alapvetően 3 fajtáját különböztetjük meg:

  • Validation Attributes: validációs célokra
  • Display Attributes: a UI-on való megjelenítéshez
  • Modelling Attributes: az osztályok közötti kapcsolatok meghatározására

Használata:

1
2
[Display(Name = "Hero name")] //a UI-on HeroName helyett a Hero name string fog megjelenni
public string HeroName {get; set;}

Az annotáció mindig az adott osztály/property fölé fog kerülni szögletes zárójelek közé. Egyszerre több megadása is lehetséges külön-külön definiálva.

Model osztályok

Első lépésként a model osztályainkat fogjuk létrehozni data annotation hozzáadásával. Adjunk egy új osztályt a Models mappánkhoz Hero néven:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;

namespace HereosWeb.Models
{
    public class Hero
    {
        [Key]
        public int ID { get; set; }

        [Required]
        public string Name { get; set; }

        [Required]
        public string HeroName { get; set; }

        [Required]
        public string Power { get; set; }

        [Required]
        public int Age { get; set; }
    }
}

Majd készítsünk egy új model osztályt Item néven:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
namespace HereosWithVS.Models
{
    public class Item
    {
        [Key]
        public int ID { get; set; }

        [Required]
        [ForeignKey("ReferencedHero")]
        public int HeroId { get; set; }

        [Required]
        public string Name { get; set; }

        public virtual Hero ReferencedHero { get; set; }
    }
}

A virtual ReferencedHero segítségével fogjuk a két osztály közötti kapcsolatot meghatározni. Ez a kapcsolat fog külső kulcs segítségével az adatbázistáblák között is megmutatkozni.

DbContext hozzáadása, konfigurálása

Hozzunk létre egy Context mappát, és ebbe készítsük el a DbContextünket, EFContext néven. Az EFContext osztályunkat származtassuk a DbContext osztályból (using Microsoft.EntityFrameworkCore), és lássuk el Heroes és Items property-kkel, amik majd az adatbázis tábláinkat fogják reprezentálni.

Majd írjuk felül az ősosztály OnConfiguring metódusát a következőképpen:

1
2
3
4
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlite("Data Source=.//DB//heroes.db");
}

A megadott útvonalra szeretnénk ha kerülne az adatbázisunk (hozzuk létre a DB mappát neki).

Most regisztráljuk a létrehozott DbContextünket, hogy a későbbiekben globálisan bárhonnan használhassuk azt. Ezt a Startup.cs-ben tehetjük meg. Keressük meg a ConfigureServices metódust és adjuk hozzá a következő sort:

1
 services.AddDbContext<EFContext>();

Majd a Configure metódushoz adjuk hozzá a következő kódrészletet az app.UseMvc() elé:

1
2
3
4
app.UseCors(builder => builder
.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin());

EntityFramework Code First Migrations

[EntityFramework-ös jegyzet] A megközelítés lényege, hogy először az osztályok kerülnek létrehozásra, majd a keretrendszer létrehozza ezek alapján az SQL táblákat. A kód változását úgynevezett migrációk segítségével lehet követni, ami hasonló egy git commithoz. A modell változása után egy migráció létrehozásával az utolsó pillanatkép óta történt változásokat menti le (pl. átnevezés, új property hozzáadása, törlése, stb).

A migrációk rendelkezni fognak Up és Down metódusokkal, az újonnan létrehozott/hozzáadott/módosított és a törölt változtatások kezelésére. Az egyes migrációkat hozzáadhatjuk és visszavonhatjuk (visszaugorhatunk a korábbi állapotra) az adatbázis sémánkhoz.

Maga a migráció egy automatikus folyamat lesz, az egyes migrációs fájlokat generálni fogjuk a model osztályokban történt változások alapján. Ezt EF6-ban nem tudtuk kipróbálni az sqlite-tal, de a webes projekt alatt (lévén .NET Core lesz alatta) már ki tudjuk próbálni.

Az adatbázis és a táblák létrehozása

Most hogy létrehoztuk a model osztályokat és a DbContextünk, a következő lépés, hogy ezek alapján elkészítjük az adatbázisunkat a Code First segítségével. Ehhez migration-t fogunk definiálni. A legelső migration-ünk gondoskodni fog az adatbázisunk és a tábláink létrehozásáról. Minden változtatás után a model osztályainkban, létre fogunk hozni egy új migration-t és frissíteni fogjuk az adatbázist a változtatások alapján.

  1. Visual Studioban
  2. nyissunk egy Package Manager Console-t
  3. hozzuk létre az Inital migrációnkat InitialCreate néven a következő paranccsal: Add-Migration InitialCreate
  4. VS Code-ban
  5. nyissunk egy terminált
  6. adjuk ki a dotnet ef migrations add InitialCreate parancsot

Ha mindent jól csináltunk létrejött egy Migrations mappa, amiben többek között az InitialCreate migration-ünk is szerepel. Nézzük meg az Up és Down metódusokat.

  1. Ahhoz, hogy a migration-ünk le is fusson frissítenünk kell az adatbázist ezt Visual Studioban az update-database paranccsal, terminálból pedig a dotnet ef database update paranccsal tehetjük meg

Vizsgáljuk meg az így létrehozott adatbázisunk sémáját.

Hero action-ök

Add/Create Hero

Készítsünk egy HeroesControllert a Controller mappába. A HeroesController származzon a Microsoft.AspNetCore.Mvc.Controller osztályból.

Tipp: usingok, amik kelleni fognak:

1
2
3
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

Hozzunk létre egy context adattagot.

1
private readonly EFContext _context;

Készítsük el a megfelelő metódusokat a hős létrehozáshoz. Először egy Create page-re lesz szükségünk egy form-mal amit kitölthetünk az új hősünk adataival. Ehhez szükségünk lesz egy Create (Get) metódusra, ami megjeleníti a megfelelő View page-et a formmal.

1
2
3
4
public IActionResult Create()
{
    return View();
}

Ez a metódus a Heroes/Create.cshtml view-t fogja keresni és megjeleníteni a böngészőben, ezért hozzuk létre a Heroes/Create.cshtml fájlt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@model HeroesWeb.Models.Hero
<h1>Create</h1>
<div class="row">
<div class="col-md-4">
    <form asp-action="Create">
        <div class="form-group">
            <label asp-for="Name" class="control-label"></label>
            <input asp-for="Name" class="form-control" />
        </div>
         <div class="form-group">
            <label asp-for="HeroName" class="control-label"></label>
            <input asp-for="HeroName" class="form-control" />
        </div>
         <div class="form-group">
            <label asp-for="Power" class="control-label"></label>
            <input asp-for="Power" class="form-control" />
        </div>
         <div class="form-group">
            <label asp-for="Age" class="control-label"></label>
            <input asp-for="Age" class="form-control" />
        </div>
        <div class="form-group">
            <input type="submit" value="Create" class="btn btn-primary" />
        </div>
    </form>
</div>
</div>

<div>
    <a asp-action="Index">Back to list</a>
</div>

Most írjuk meg a controllerben azt a metódust ami elmenti a Hero-t az adatbázisba a Create gombra kattintva (Post).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,Name,HeroName,Power,Age")] Hero hero)
{
    if(ModelState.IsValid){
        _context.Add(hero);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }

    return View(hero);
}

List Heroes

Készítsünk egy Index.cshtml-t és egy Index actiont, ami kilistázza az adatbázisban szereplő hőseinket.

1
2
3
4
public async Task<IActionResult> Index(){
    var heroes = await _context.Heroes.ToListAsync();
    return View(heroes);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@model IEnumerable<HeroesWeb.Models.Hero>

<h1>index</h1>
<a asp-action="Create">Create new</a>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(m => m.Name)
        </th>
        <th>
            @Html.DisplayNameFor(m => m.HeroName)
        </th>
        <th>
            @Html.DisplayNameFor(m => m.Power)
        </th>
        <th>
            @Html.DisplayNameFor(m => m.Age)
        </th>
    </tr>
    @foreach (var item in Model){
    <tr>
        <td>
            @Html.DisplayFor(m => item.Name)
        </td>
        <td>
            @Html.DisplayFor(m => item.HeroName)
        </td>
        <td>
            @Html.DisplayFor(m => item.Power)
        </td>
        <td>
            @Html.DisplayFor(m => item.Age)
        </td>
    </tr>
    }
</table>

Végül rakjuk be a létrehozott oldalainkat a navbar-ba.


Utolsó frissítés: 2023-08-07 09:17:05