Megosztás a következőn keresztül:


6. rész, vezérlőmódszerek és nézetek a ASP.NET Core-ban

Megjegyzés:

Ez nem a cikk legújabb verziója. Az aktuális kiadásról a cikk .NET 10-es verziójában olvashat.

Figyelmeztetés

A ASP.NET Core ezen verziója már nem támogatott. További információt a .NET és a .NET Core támogatási szabályzatában talál. A jelen cikk .NET 9-es verzióját lásd az aktuális kiadásért .

Készítette: Rick Anderson

Jól kezdtük a filmalkalmazást, de a bemutató nem ideális, például a ReleaseDate-nek két szónak kell lennie.

Index nézet: A kiadási dátum egy szó (szóköz nélkül), és minden film kiadási dátuma éjfélkor jelenik meg

Nyissa meg a Models/Movie.cs fájlt, és adja hozzá az alább látható kiemelt sorokat:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }
    
    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
}

DataAnnotations a következő oktatóanyagban kerül ismertetésre. A Megjelenítés attribútum határozza meg, hogy mit kell megjeleníteni egy mező nevének (ebben az esetben a "ReleaseDate" helyett a "ReleaseDate" értéket). A DataType attribútum megadja az adatok típusát (Dátum), így a mezőben tárolt időadatok nem jelennek meg.

A fenti adatjegyzetek használatával futtassa az alkalmazást, és frissítse a /Movies lapot. Mivel a nézet jelölés a @Html.DisplayNameFor és @Html.DisplayFor metódusokat használja a tulajdonságnév és az érték megjelenítésére, a frissített Index nézet az összes mezőt megfelelően formázza. A kiadás dátuma például most már két különálló szóból áll, és az időinformáció már nem jelenik meg.

Index nézet: Az

Az [Column(TypeName = "decimal(18, 2)")] adatjegyzetre van szükség ahhoz, hogy az Entity Framework Core megfelelően le tudja képezni az Price-et az adatbázisban pénznemként. További információ: adattípusok.

Keresse meg a vezérlőt Movies , és tartsa lenyomva az egérmutatót egy Szerkesztés hivatkozás felett a cél URL-címének megtekintéséhez.

A böngészőablak látható, ahol az egér a Szerkesztés hivatkozáson van, és megjelenik egy hivatkozás URL-je: https://localhost:5001/Movies/Edit/5

A szerkesztési, részletes és törlési hivatkozásokat a fájl alapvető MVC horgonycímke-segédje Views/Movies/Index.cshtml hozza létre.

        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
    </td>
</tr>

A címkesegédek lehetővé teszik, hogy a kiszolgálóoldali kód részt vegyen a HTML-elemek Razor fájlokban történő létrehozásában és megjelenítésében. A fenti kódban a AnchorTagHelper HTML href attribútum értéke dinamikusan jön létre a vezérlő műveleti metódusa és az útvonalazonosító alapján. A Forrás megtekintése funkciót a kedvenc böngészőjében használhatja, vagy a fejlesztői eszközöket használva vizsgálhatja meg a létrehozott jelölést. A létrehozott HTML egy része az alábbiakban látható:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

A fájlban megadott útválasztási beállítás formátumának felidézése Program.cs.

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ASP.NET Core a https://localhost:5001/Movies/Edit/4 vezérlő Edit műveletmetódusára fordítja le a Movies-t, 4-es Id paraméterrel ellátva a kérést. (A vezérlőmetelyeket műveleti metódusnak is nevezik.)

A Tag Helpers a ASP.NET Core egyik legnépszerűbb új funkciója. További információ: További erőforrások.

Nyissa meg a vezérlőt Movies , és vizsgálja meg a két Edit műveleti módszert. Az alábbi kód azt a metódust HTTP GET Edit mutatja be, amely beolvassa a filmet, és feltölti a fájl által létrehozott szerkesztési Edit.cshtmlRazor űrlapot.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Az alábbi kód a HTTP POST Edit közzétett filmértékeket feldolgozó metódust mutatja be:

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az [Bind] attribútum az egyik módja annak, hogy védelmet nyújtsunk a túlzott közzététel ellen. Kizárólag azokat a tulajdonságokat szabad beilleszteni a [Bind] attribútumba, amelyeket módosítani kíván. További információért lásd: A vezérlő túlterhelésével szembeni védelem. A ViewModels alternatív módszert kínál a túlküldés megelőzésére.

Figyelje meg, hogy a második Edit műveleti metódust az [HttpPost] attribútum előzi meg.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az HttpPost attribútum azt határozza meg, hogy ez a Edit metódus kérések esetén POST hívható meg. Az attribútumot alkalmazhatja az [HttpGet] első szerkesztési módszerre, de ez nem szükséges, mert [HttpGet] ez az alapértelmezett érték.

Az ValidateAntiForgeryToken attribútum a kérések hamisításának megelőzésére szolgál, és a szerkesztési nézetfájlban (Views/Movies/Edit.cshtml) létrehozott antiforgery jogkivonattal van párosítva. A szerkesztési nézetfájl létrehozza az antiforgery jogkivonatot az űrlapcímke segédjével.

<form asp-action="Edit">

Az űrlapcímke-segéd létrehoz egy rejtett antiforgery tokent, amely meg kell egyeznie a [ValidateAntiForgeryToken] létrehozott antiforgery tokennel a Edit Filmek vezérlő metódusában. További információért lásd: Az ASP.NET Core alkalmazásban történő helyek közötti kéréshamisítás (XSRF/CSRF) elleni támadások megakadályozása.

A HttpGet Edit metódus felveszi a mozgókép ID paraméterét, megkeresi a filmet az Entity Framework FindAsync metódussal, és visszaadja a kijelölt filmet a Szerkesztés nézetbe. Ha nem található film, NotFound a rendszer a HTTP 404-et adja vissza.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Amikor az állványzatrendszer létrehozta a Szerkesztés nézetet, megvizsgálta az Movie osztályt, és kódot hozott létre az osztály minden tulajdonságához, hogy megjelenítse a <label> és <input> elemeket. Az alábbi példa a Visual Studio állványrendszer által létrehozott Szerkesztés nézetet mutatja be:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Id" />
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ReleaseDate" class="control-label"></label>
                <input asp-for="ReleaseDate" class="form-control" />
                <span asp-validation-for="ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Price" class="control-label"></label>
                <input asp-for="Price" class="form-control" />
                <span asp-validation-for="Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Figyelje meg, hogy a nézetsablonnak van egy @model MvcMovie.Models.Movie utasítása a fájl tetején. @model MvcMovie.Models.Movie azt határozza meg, hogy a nézet azt várja, hogy a nézetsablon típusa típus Movielegyen.

A sablonozott kód több Tag Helper metódust használ a HTML-jelölés egyszerűsítéséhez. A Címkecímke segéd megjeleníti a mező nevét ("Cím", "ReleaseDate", "Műfaj" vagy "Ár"). A beviteli címke súgója HTML-elemet <input> jelenít meg. Az Érvényesítési címke súgója megjeleníti az adott tulajdonsághoz társított érvényesítési üzeneteket.

Futtassa az alkalmazást, és keresse meg az /Movies URL-címet. Kattintson egy Szerkesztés hivatkozásra. A böngészőben tekintse meg a lap forrását. Az elemhez létrehozott HTML az <form> alábbiakban látható.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Az <input> elemek olyan HTML <form> elemben találhatók, amelynek action attribútuma közzétételre az /Movies/Edit/id URL-címhez van beállítva. Az űrlapadatok a gombra kattintáskor lesznek közzétéve a Save kiszolgálón. A záró </form> elem előtti utolsó sor a XSRF rejtett token-t jeleníti meg, amelyet a Form Tag Helper generált.

A POST-kérelem feldolgozása

Az alábbi lista a [HttpPost] műveletmetódus Edit verzióját mutatja.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az [ValidateAntiForgeryToken] attribútum ellenőrzi az űrlapcímke-segédben az antiforgery tokengenerátor által létrehozott rejtett XSRF-jogkivonatot

A modellkötési rendszer összegyűjti a közzétett űrlapértékeket, és létrehoz egy objektumot, amelyet Movie paraméterként ad át. A ModelState.IsValid tulajdonság ellenőrzi, hogy az űrlapon elküldött adatok felhasználhatók-e egy Movie objektum módosítására (szerkesztésére vagy frissítésére). Ha az adatai érvényesek, akkor azok a rendszer által lesznek mentve. A frissített (szerkesztett) filmadatokat az adatbáziskontekstus SaveChangesAsync metódusának meghívásával mentjük el az adatbázisba. Az adatok mentése után a kód átirányítja a felhasználót az IndexMoviesController osztály műveleti módszerére, amely megjeleníti a filmgyűjteményt, beleértve az imént végrehajtott módosításokat is.

Mielőtt az űrlapot közzétennénk a kiszolgálóra, az ügyféloldali ellenőrzés ellenőrzi a mezők érvényesítési szabályait. Ha ellenőrzési hibák történnek, hibaüzenet jelenik meg, és az űrlap nem lesz közzétéve. Ha a JavaScript le van tiltva, akkor nem fog ügyféloldali ellenőrzést alkalmazni, de a kiszolgáló észleli a nem érvényes közzétett értékeket, és az űrlapértékek hibaüzenetekkel jelennek meg. Az oktatóanyag későbbi részében részletesebben vizsgáljuk meg a modellérvényesítést . A nézetsablon Érvényesítési címke segédje gondoskodik a Views/Movies/Edit.cshtml megfelelő hibaüzenetek megjelenítéséről.

Szerkesztési nézet: Az abc helytelen árértékére vonatkozó kivétel azt állítja, hogy az Ár mezőnek számnak kell lennie. A xyz helytelen kiadási dátumértékére vonatkozó kivétel azt mondja, hogy Kérjük, adjon meg érvényes dátumot.

A filmvezérlő összes metódusa HttpGet hasonló mintát követ. Lekérnek egy mozgóképobjektumot (vagy objektumlistát, abban az esetben Index), és átadják az objektumot (modellt) a nézetnek. A Create metódus egy üres filmobjektumot ad át a Create nézetnek. Minden olyan metódus, amely adatokat hoz létre, szerkeszt, töröl vagy más módon módosít, a [HttpPost] metódus túlterhelése esetén ezt teszi. Egy metódus adatainak HTTP GET módosítása biztonsági kockázatot jelent. Az adatok metódusban HTTP GET való módosítása a HTTP ajánlott eljárásait és az architektúramintát REST is sérti, amely azt határozza meg, hogy a GET-kérések nem módosíthatják az alkalmazás állapotát. Más szóval a GET művelet végrehajtásának olyan biztonságos műveletnek kell lennie, amelynek nincsenek mellékhatásai, és nem módosítja a tárolt adatokat.

További erőforrások

Jól kezdtük a filmalkalmazást, de a bemutató nem ideális, például a ReleaseDate-nek két szónak kell lennie.

Index nézet: A kiadási dátum egy szó (szóköz nélkül), és minden film kiadási dátuma éjfélkor jelenik meg

Nyissa meg a Models/Movie.cs fájlt, és adja hozzá az alább látható kiemelt sorokat:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }
    
    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
}

DataAnnotations a következő oktatóanyagban kerül ismertetésre. A Megjelenítés attribútum határozza meg, hogy mit kell megjeleníteni egy mező nevének (ebben az esetben a "ReleaseDate" helyett a "ReleaseDate" értéket). A DataType attribútum megadja az adatok típusát (Dátum), így a mezőben tárolt időadatok nem jelennek meg.

Az [Column(TypeName = "decimal(18, 2)")] adatjegyzetre van szükség ahhoz, hogy az Entity Framework Core megfelelően le tudja képezni az Price-et az adatbázisban pénznemként. További információ: adattípusok.

Keresse meg a vezérlőt Movies , és tartsa lenyomva az egérmutatót egy Szerkesztés hivatkozás felett a cél URL-címének megtekintéséhez.

A böngészőablak látható, ahol az egér a Szerkesztés hivatkozáson van, és megjelenik egy hivatkozás URL-je: https://localhost:5001/Movies/Edit/5

A szerkesztési, részletes és törlési hivatkozásokat a fájl alapvető MVC horgonycímke-segédje Views/Movies/Index.cshtml hozza létre.

        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
    </td>
</tr>

A címkesegédek lehetővé teszik, hogy a kiszolgálóoldali kód részt vegyen a HTML-elemek Razor fájlokban történő létrehozásában és megjelenítésében. A fenti kódban a AnchorTagHelper HTML href attribútum értéke dinamikusan jön létre a vezérlő műveleti metódusa és az útvonalazonosító alapján. A Forrás megtekintése funkciót a kedvenc böngészőjében használhatja, vagy a fejlesztői eszközöket használva vizsgálhatja meg a létrehozott jelölést. A létrehozott HTML egy része az alábbiakban látható:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

A fájlban megadott útválasztási beállítás formátumának felidézése Program.cs.

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ASP.NET Core a https://localhost:5001/Movies/Edit/4 vezérlő Edit műveletmetódusára fordítja le a Movies-t, 4-es Id paraméterrel ellátva a kérést. (A vezérlőmetelyeket műveleti metódusnak is nevezik.)

A Tag Helpers a ASP.NET Core egyik legnépszerűbb új funkciója. További információ: További erőforrások.

Nyissa meg a vezérlőt Movies , és vizsgálja meg a két Edit műveleti módszert. Az alábbi kód azt a metódust HTTP GET Edit mutatja be, amely beolvassa a filmet, és feltölti a fájl által létrehozott szerkesztési Edit.cshtmlRazor űrlapot.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Az alábbi kód a HTTP POST Edit közzétett filmértékeket feldolgozó metódust mutatja be:

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az [Bind] attribútum az egyik módja annak, hogy védelmet nyújtsunk a túlzott közzététel ellen. Kizárólag azokat a tulajdonságokat szabad beilleszteni a [Bind] attribútumba, amelyeket módosítani kíván. További információért lásd: A vezérlő túlterhelésével szembeni védelem. A ViewModels alternatív módszert kínál a túlküldés megelőzésére.

Figyelje meg, hogy a második Edit műveleti metódust az [HttpPost] attribútum előzi meg.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az HttpPost attribútum azt határozza meg, hogy ez a Edit metódus kérések esetén POST hívható meg. Az attribútumot alkalmazhatja az [HttpGet] első szerkesztési módszerre, de ez nem szükséges, mert [HttpGet] ez az alapértelmezett érték.

Az ValidateAntiForgeryToken attribútum a kérések hamisításának megelőzésére szolgál, és a szerkesztési nézetfájlban (Views/Movies/Edit.cshtml) létrehozott antiforgery jogkivonattal van párosítva. A szerkesztési nézetfájl létrehozza az antiforgery jogkivonatot az űrlapcímke segédjével.

<form asp-action="Edit">

Az űrlapcímke-segéd létrehoz egy rejtett antiforgery tokent, amely meg kell egyeznie a [ValidateAntiForgeryToken] létrehozott antiforgery tokennel a Edit Filmek vezérlő metódusában. További információért lásd: Az ASP.NET Core alkalmazásban történő helyek közötti kéréshamisítás (XSRF/CSRF) elleni támadások megakadályozása.

A HttpGet Edit metódus felveszi a mozgókép ID paraméterét, megkeresi a filmet az Entity Framework FindAsync metódussal, és visszaadja a kijelölt filmet a Szerkesztés nézetbe. Ha nem található film, NotFound a rendszer a HTTP 404-et adja vissza.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Amikor az állványzatrendszer létrehozta a Szerkesztés nézetet, megvizsgálta az Movie osztályt, és kódot hozott létre az osztály minden tulajdonságához, hogy megjelenítse a <label> és <input> elemeket. Az alábbi példa a Visual Studio állványrendszer által létrehozott Szerkesztés nézetet mutatja be:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Id" />
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ReleaseDate" class="control-label"></label>
                <input asp-for="ReleaseDate" class="form-control" />
                <span asp-validation-for="ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Price" class="control-label"></label>
                <input asp-for="Price" class="form-control" />
                <span asp-validation-for="Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Figyelje meg, hogy a nézetsablonnak van egy @model MvcMovie.Models.Movie utasítása a fájl tetején. @model MvcMovie.Models.Movie azt határozza meg, hogy a nézet azt várja, hogy a nézetsablon típusa típus Movielegyen.

A sablonozott kód több Tag Helper metódust használ a HTML-jelölés egyszerűsítéséhez. A Címkecímke segéd megjeleníti a mező nevét ("Cím", "ReleaseDate", "Műfaj" vagy "Ár"). A beviteli címke súgója HTML-elemet <input> jelenít meg. Az Érvényesítési címke súgója megjeleníti az adott tulajdonsághoz társított érvényesítési üzeneteket.

Futtassa az alkalmazást, és keresse meg az /Movies URL-címet. Kattintson egy Szerkesztés hivatkozásra. A böngészőben tekintse meg a lap forrását. Az elemhez létrehozott HTML az <form> alábbiakban látható.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Az <input> elemek olyan HTML <form> elemben találhatók, amelynek action attribútuma közzétételre az /Movies/Edit/id URL-címhez van beállítva. Az űrlapadatok a gombra kattintáskor lesznek közzétéve a Save kiszolgálón. A záró </form> elem előtti utolsó sor a XSRF rejtett token-t jeleníti meg, amelyet a Form Tag Helper generált.

A POST-kérelem feldolgozása

Az alábbi lista a [HttpPost] műveletmetódus Edit verzióját mutatja.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az [ValidateAntiForgeryToken] attribútum ellenőrzi az űrlapcímke-segédben az antiforgery tokengenerátor által létrehozott rejtett XSRF-jogkivonatot

A modellkötési rendszer összegyűjti a közzétett űrlapértékeket, és létrehoz egy objektumot, amelyet Movie paraméterként ad át. A ModelState.IsValid tulajdonság ellenőrzi, hogy az űrlapon elküldött adatok felhasználhatók-e egy Movie objektum módosítására (szerkesztésére vagy frissítésére). Ha az adatai érvényesek, akkor azok a rendszer által lesznek mentve. A frissített (szerkesztett) filmadatokat az adatbáziskontekstus SaveChangesAsync metódusának meghívásával mentjük el az adatbázisba. Az adatok mentése után a kód átirányítja a felhasználót az IndexMoviesController osztály műveleti módszerére, amely megjeleníti a filmgyűjteményt, beleértve az imént végrehajtott módosításokat is.

Mielőtt az űrlapot közzétennénk a kiszolgálóra, az ügyféloldali ellenőrzés ellenőrzi a mezők érvényesítési szabályait. Ha ellenőrzési hibák történnek, hibaüzenet jelenik meg, és az űrlap nem lesz közzétéve. Ha a JavaScript le van tiltva, akkor nem fog ügyféloldali ellenőrzést alkalmazni, de a kiszolgáló észleli a nem érvényes közzétett értékeket, és az űrlapértékek hibaüzenetekkel jelennek meg. Az oktatóanyag későbbi részében részletesebben vizsgáljuk meg a modellérvényesítést . A nézetsablon Érvényesítési címke segédje gondoskodik a Views/Movies/Edit.cshtml megfelelő hibaüzenetek megjelenítéséről.

Szerkesztési nézet: Az abc helytelen árértékére vonatkozó kivétel azt állítja, hogy az Ár mezőnek számnak kell lennie. A xyz helytelen kiadási dátumértékére vonatkozó kivétel azt mondja, hogy Kérjük, adjon meg érvényes dátumot.

A filmvezérlő összes metódusa HttpGet hasonló mintát követ. Lekérnek egy mozgóképobjektumot (vagy objektumlistát, abban az esetben Index), és átadják az objektumot (modellt) a nézetnek. A Create metódus egy üres filmobjektumot ad át a Create nézetnek. Minden olyan metódus, amely adatokat hoz létre, szerkeszt, töröl vagy más módon módosít, a [HttpPost] metódus túlterhelése esetén ezt teszi. Egy metódus adatainak HTTP GET módosítása biztonsági kockázatot jelent. Az adatok metódusban HTTP GET való módosítása a HTTP ajánlott eljárásait és az architektúramintát REST is sérti, amely azt határozza meg, hogy a GET-kérések nem módosíthatják az alkalmazás állapotát. Más szóval a GET művelet végrehajtásának olyan biztonságos műveletnek kell lennie, amelynek nincsenek mellékhatásai, és nem módosítja a tárolt adatokat.

További erőforrások

Jól kezdtük a filmalkalmazást, de a bemutató nem ideális, például a ReleaseDate-nek két szónak kell lennie.

Index nézet: A kiadási dátum egy szó (szóköz nélkül), és minden film kiadási dátuma éjfélkor jelenik meg

Nyissa meg a Models/Movie.cs fájlt, és adja hozzá az alább látható kiemelt sorokat:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }
    
    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
}

DataAnnotations a következő oktatóanyagban kerül ismertetésre. A Megjelenítés attribútum határozza meg, hogy mit kell megjeleníteni egy mező nevének (ebben az esetben a "ReleaseDate" helyett a "ReleaseDate" értéket). A DataType attribútum megadja az adatok típusát (Dátum), így a mezőben tárolt időadatok nem jelennek meg.

Az [Column(TypeName = "decimal(18, 2)")] adatjegyzetre van szükség ahhoz, hogy az Entity Framework Core megfelelően le tudja képezni az Price-et az adatbázisban pénznemként. További információ: adattípusok.

Keresse meg a vezérlőt Movies , és tartsa lenyomva az egérmutatót egy Szerkesztés hivatkozás felett a cél URL-címének megtekintéséhez.

A böngészőablak látható, ahol az egér a Szerkesztés hivatkozáson van, és megjelenik egy hivatkozás URL-je: https://localhost:5001/Movies/Edit/5

A szerkesztési, részletes és törlési hivatkozásokat a fájl alapvető MVC horgonycímke-segédje Views/Movies/Index.cshtml hozza létre.

        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
    </td>
</tr>

A címkesegédek lehetővé teszik, hogy a kiszolgálóoldali kód részt vegyen a HTML-elemek Razor fájlokban történő létrehozásában és megjelenítésében. A fenti kódban a AnchorTagHelper HTML href attribútum értéke dinamikusan jön létre a vezérlő műveleti metódusa és az útvonalazonosító alapján. A Forrás megtekintése funkciót a kedvenc böngészőjében használhatja, vagy a fejlesztői eszközöket használva vizsgálhatja meg a létrehozott jelölést. A létrehozott HTML egy része az alábbiakban látható:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

A fájlban megadott útválasztási beállítás formátumának felidézése Program.cs.

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ASP.NET Core a https://localhost:5001/Movies/Edit/4 vezérlő Edit műveletmetódusára fordítja le a Movies-t, 4-es Id paraméterrel ellátva a kérést. (A vezérlőmetelyeket műveleti metódusnak is nevezik.)

A Tag Helpers a ASP.NET Core egyik legnépszerűbb új funkciója. További információ: További erőforrások.

Nyissa meg a vezérlőt Movies , és vizsgálja meg a két Edit műveleti módszert. Az alábbi kód azt a metódust HTTP GET Edit mutatja be, amely beolvassa a filmet, és feltölti a fájl által létrehozott szerkesztési Edit.cshtmlRazor űrlapot.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Az alábbi kód a HTTP POST Edit közzétett filmértékeket feldolgozó metódust mutatja be:

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az [Bind] attribútum az egyik módja annak, hogy védelmet nyújtsunk a túlzott közzététel ellen. Kizárólag azokat a tulajdonságokat szabad beilleszteni a [Bind] attribútumba, amelyeket módosítani kíván. További információért lásd: A vezérlő túlterhelésével szembeni védelem. A ViewModels alternatív módszert kínál a túlküldés megelőzésére.

Figyelje meg, hogy a második Edit műveleti metódust az [HttpPost] attribútum előzi meg.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az HttpPost attribútum azt határozza meg, hogy ez a Edit metódus kérések esetén POST hívható meg. Az attribútumot alkalmazhatja az [HttpGet] első szerkesztési módszerre, de ez nem szükséges, mert [HttpGet] ez az alapértelmezett érték.

Az ValidateAntiForgeryToken attribútum a kérések hamisításának megelőzésére szolgál, és a szerkesztési nézetfájlban (Views/Movies/Edit.cshtml) létrehozott antiforgery jogkivonattal van párosítva. A szerkesztési nézetfájl létrehozza az antiforgery jogkivonatot az űrlapcímke segédjével.

<form asp-action="Edit">

Az űrlapcímke-segéd létrehoz egy rejtett antiforgery tokent, amely meg kell egyeznie a [ValidateAntiForgeryToken] létrehozott antiforgery tokennel a Edit Filmek vezérlő metódusában. További információért lásd: Az ASP.NET Core alkalmazásban történő helyek közötti kéréshamisítás (XSRF/CSRF) elleni támadások megakadályozása.

A HttpGet Edit metódus felveszi a mozgókép ID paraméterét, megkeresi a filmet az Entity Framework FindAsync metódussal, és visszaadja a kijelölt filmet a Szerkesztés nézetbe. Ha nem található film, NotFound a rendszer a HTTP 404-et adja vissza.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Amikor az állványzatrendszer létrehozta a Szerkesztés nézetet, megvizsgálta az Movie osztályt, és kódot hozott létre az osztály minden tulajdonságához, hogy megjelenítse a <label> és <input> elemeket. Az alábbi példa a Visual Studio állványrendszer által létrehozott Szerkesztés nézetet mutatja be:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Id" />
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ReleaseDate" class="control-label"></label>
                <input asp-for="ReleaseDate" class="form-control" />
                <span asp-validation-for="ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Price" class="control-label"></label>
                <input asp-for="Price" class="form-control" />
                <span asp-validation-for="Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Figyelje meg, hogy a nézetsablonnak van egy @model MvcMovie.Models.Movie utasítása a fájl tetején. @model MvcMovie.Models.Movie azt határozza meg, hogy a nézet azt várja, hogy a nézetsablon típusa típus Movielegyen.

A sablonozott kód több Tag Helper metódust használ a HTML-jelölés egyszerűsítéséhez. A Címkecímke segéd megjeleníti a mező nevét ("Cím", "ReleaseDate", "Műfaj" vagy "Ár"). A beviteli címke súgója HTML-elemet <input> jelenít meg. Az Érvényesítési címke súgója megjeleníti az adott tulajdonsághoz társított érvényesítési üzeneteket.

Futtassa az alkalmazást, és keresse meg az /Movies URL-címet. Kattintson egy Szerkesztés hivatkozásra. A böngészőben tekintse meg a lap forrását. Az elemhez létrehozott HTML az <form> alábbiakban látható.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Az <input> elemek olyan HTML <form> elemben találhatók, amelynek action attribútuma közzétételre az /Movies/Edit/id URL-címhez van beállítva. Az űrlapadatok a gombra kattintáskor lesznek közzétéve a Save kiszolgálón. A záró </form> elem előtti utolsó sor a XSRF rejtett token-t jeleníti meg, amelyet a Form Tag Helper generált.

A POST-kérelem feldolgozása

Az alábbi lista a [HttpPost] műveletmetódus Edit verzióját mutatja.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az [ValidateAntiForgeryToken] attribútum ellenőrzi az űrlapcímke-segédben az antiforgery tokengenerátor által létrehozott rejtett XSRF-jogkivonatot

A modellkötési rendszer összegyűjti a közzétett űrlapértékeket, és létrehoz egy objektumot, amelyet Movie paraméterként ad át. A ModelState.IsValid tulajdonság ellenőrzi, hogy az űrlapon elküldött adatok felhasználhatók-e egy Movie objektum módosítására (szerkesztésére vagy frissítésére). Ha az adatai érvényesek, akkor azok a rendszer által lesznek mentve. A frissített (szerkesztett) filmadatokat az adatbáziskontekstus SaveChangesAsync metódusának meghívásával mentjük el az adatbázisba. Az adatok mentése után a kód átirányítja a felhasználót az IndexMoviesController osztály műveleti módszerére, amely megjeleníti a filmgyűjteményt, beleértve az imént végrehajtott módosításokat is.

Mielőtt az űrlapot közzétennénk a kiszolgálóra, az ügyféloldali ellenőrzés ellenőrzi a mezők érvényesítési szabályait. Ha ellenőrzési hibák történnek, hibaüzenet jelenik meg, és az űrlap nem lesz közzétéve. Ha a JavaScript le van tiltva, akkor nem fog ügyféloldali ellenőrzést alkalmazni, de a kiszolgáló észleli a nem érvényes közzétett értékeket, és az űrlapértékek hibaüzenetekkel jelennek meg. Az oktatóanyag későbbi részében részletesebben vizsgáljuk meg a modellérvényesítést . A nézetsablon Érvényesítési címke segédje gondoskodik a Views/Movies/Edit.cshtml megfelelő hibaüzenetek megjelenítéséről.

Szerkesztési nézet: Az abc helytelen árértékére vonatkozó kivétel azt állítja, hogy az Ár mezőnek számnak kell lennie. A xyz helytelen kiadási dátumértékére vonatkozó kivétel azt mondja, hogy Kérjük, adjon meg érvényes dátumot.

A filmvezérlő összes metódusa HttpGet hasonló mintát követ. Lekérnek egy mozgóképobjektumot (vagy objektumlistát, abban az esetben Index), és átadják az objektumot (modellt) a nézetnek. A Create metódus egy üres filmobjektumot ad át a Create nézetnek. Minden olyan metódus, amely adatokat hoz létre, szerkeszt, töröl vagy más módon módosít, a [HttpPost] metódus túlterhelése esetén ezt teszi. Egy metódus adatainak HTTP GET módosítása biztonsági kockázatot jelent. Az adatok metódusban HTTP GET való módosítása a HTTP ajánlott eljárásait és az architektúramintát REST is sérti, amely azt határozza meg, hogy a GET-kérések nem módosíthatják az alkalmazás állapotát. Más szóval a GET művelet végrehajtásának olyan biztonságos műveletnek kell lennie, amelynek nincsenek mellékhatásai, és nem módosítja a tárolt adatokat.

További erőforrások

Jól kezdtük a filmalkalmazást, de a bemutató nem ideális, például a ReleaseDate-nek két szónak kell lennie.

Index nézet: A kiadási dátum egy szó (szóköz nélkül), és minden film kiadási dátuma éjfélkor jelenik meg

Nyissa meg a Models/Movie.cs fájlt, és adja hozzá az alább látható kiemelt sorokat:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string? Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string? Genre { get; set; }

        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
    }
}

DataAnnotations a következő oktatóanyagban kerül ismertetésre. A Megjelenítés attribútum határozza meg, hogy mit kell megjeleníteni egy mező nevének (ebben az esetben a "ReleaseDate" helyett a "ReleaseDate" értéket). A DataType attribútum megadja az adatok típusát (Dátum), így a mezőben tárolt időadatok nem jelennek meg.

Az [Column(TypeName = "decimal(18, 2)")] adatjegyzetre van szükség ahhoz, hogy az Entity Framework Core megfelelően le tudja képezni az Price-et az adatbázisban pénznemként. További információ: adattípusok.

Keresse meg a vezérlőt Movies , és tartsa lenyomva az egérmutatót egy Szerkesztés hivatkozás felett a cél URL-címének megtekintéséhez.

A böngészőablak látható, ahol az egér a Szerkesztés hivatkozáson van, és megjelenik egy hivatkozás URL-je: https://localhost:5001/Movies/Edit/5

A szerkesztési, részletes és törlési hivatkozásokat a fájl alapvető MVC horgonycímke-segédje Views/Movies/Index.cshtml hozza létre.

        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
    </td>
</tr>

A címkesegédek lehetővé teszik, hogy a kiszolgálóoldali kód részt vegyen a HTML-elemek Razor fájlokban történő létrehozásában és megjelenítésében. A fenti kódban a AnchorTagHelper HTML href attribútum értéke dinamikusan jön létre a vezérlő műveleti metódusa és az útvonalazonosító alapján. A Forrás megtekintése funkciót a kedvenc böngészőjében használhatja, vagy a fejlesztői eszközöket használva vizsgálhatja meg a létrehozott jelölést. A létrehozott HTML egy része az alábbiakban látható:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

A fájlban megadott útválasztási beállítás formátumának felidézése Program.cs.

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ASP.NET Core a https://localhost:5001/Movies/Edit/4 vezérlő Edit műveletmetódusára fordítja le a Movies-t, 4-es Id paraméterrel ellátva a kérést. (A vezérlőmetelyeket műveleti metódusnak is nevezik.)

A címkesegédek népszerűek ASP.NET Core-ban. Ezekről további információt a További erőforrások című témakörben talál.

Nyissa meg a vezérlőt Movies , és vizsgálja meg a két Edit műveleti módszert. Az alábbi kód azt a metódust HTTP GET Edit mutatja be, amely beolvassa a filmet, és feltölti a fájl által létrehozott szerkesztési Edit.cshtmlRazor űrlapot.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Az alábbi kód a HTTP POST Edit közzétett filmértékeket feldolgozó metódust mutatja be:

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az [Bind] attribútum az egyik módja annak, hogy védelmet nyújtsunk a túlzott közzététel ellen. Kizárólag azokat a tulajdonságokat szabad beilleszteni a [Bind] attribútumba, amelyeket módosítani kíván. További információért lásd: A vezérlő túlterhelésével szembeni védelem. A ViewModels alternatív módszert kínál a túlküldés megelőzésére.

Figyelje meg, hogy a második Edit műveleti metódust az [HttpPost] attribútum előzi meg.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az HttpPost attribútum azt határozza meg, hogy ez a Edit metódus kérések esetén POST hívható meg. Az attribútumot alkalmazhatja az [HttpGet] első szerkesztési módszerre, de ez nem szükséges, mert [HttpGet] ez az alapértelmezett érték.

Az ValidateAntiForgeryToken attribútum a kérések hamisításának megelőzésére szolgál, és a szerkesztési nézetfájlban (Views/Movies/Edit.cshtml) létrehozott antiforgery jogkivonattal van párosítva. A szerkesztési nézetfájl létrehozza az antiforgery jogkivonatot az űrlapcímke segédjével.

<form asp-action="Edit">

Az űrlapcímke-segéd létrehoz egy rejtett antiforgery tokent, amely meg kell egyeznie a [ValidateAntiForgeryToken] létrehozott antiforgery tokennel a Edit Filmek vezérlő metódusában. További információért lásd: Az ASP.NET Core alkalmazásban történő helyek közötti kéréshamisítás (XSRF/CSRF) elleni támadások megakadályozása.

A HttpGet Edit metódus felveszi a mozgókép ID paraméterét, megkeresi a filmet az Entity Framework FindAsync metódussal, és visszaadja a kijelölt filmet a Szerkesztés nézetbe. Ha nem található film, NotFound a rendszer a HTTP 404-et adja vissza.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Amikor az állványzatrendszer létrehozta a Szerkesztés nézetet, megvizsgálta az Movie osztályt, és kódot hozott létre az osztály minden tulajdonságához, hogy megjelenítse a <label> és <input> elemeket. Az alábbi példa a Visual Studio állványrendszer által létrehozott Szerkesztés nézetet mutatja be:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Id" />
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ReleaseDate" class="control-label"></label>
                <input asp-for="ReleaseDate" class="form-control" />
                <span asp-validation-for="ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Price" class="control-label"></label>
                <input asp-for="Price" class="form-control" />
                <span asp-validation-for="Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Figyelje meg, hogy a nézetsablonnak van egy @model MvcMovie.Models.Movie utasítása a fájl tetején. @model MvcMovie.Models.Movie azt határozza meg, hogy a nézet azt várja, hogy a nézetsablon típusa típus Movielegyen.

A sablonozott kód több Tag Helper metódust használ a HTML-jelölés egyszerűsítéséhez. A Címkecímke segéd megjeleníti a mező nevét ("Cím", "ReleaseDate", "Műfaj" vagy "Ár"). A beviteli címke súgója HTML-elemet <input> jelenít meg. Az Érvényesítési címke súgója megjeleníti az adott tulajdonsághoz társított érvényesítési üzeneteket.

Futtassa az alkalmazást, és keresse meg az /Movies URL-címet. Kattintson egy Szerkesztés hivatkozásra. A böngészőben tekintse meg a lap forrását. Az elemhez létrehozott HTML az <form> alábbiakban látható.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Az <input> elemek olyan HTML <form> elemben találhatók, amelynek action attribútuma közzétételre az /Movies/Edit/id URL-címhez van beállítva. Az űrlapadatok a gombra kattintáskor lesznek közzétéve a Save kiszolgálón. A záró </form> elem előtti utolsó sor a XSRF rejtett token-t jeleníti meg, amelyet a Form Tag Helper generált.

A POST-kérelem feldolgozása

Az alábbi lista a [HttpPost] műveletmetódus Edit verzióját mutatja.

// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (id != movie.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az [ValidateAntiForgeryToken] attribútum ellenőrzi az űrlapcímke-segédben az antiforgery tokengenerátor által létrehozott rejtett XSRF-jogkivonatot

A modellkötési rendszer összegyűjti a közzétett űrlapértékeket, és létrehoz egy objektumot, amelyet Movie paraméterként ad át. A ModelState.IsValid tulajdonság ellenőrzi, hogy az űrlapon elküldött adatok felhasználhatók-e egy Movie objektum módosítására (szerkesztésére vagy frissítésére). Ha az adatai érvényesek, akkor azok a rendszer által lesznek mentve. A frissített (szerkesztett) filmadatokat az adatbáziskontekstus SaveChangesAsync metódusának meghívásával mentjük el az adatbázisba. Az adatok mentése után a kód átirányítja a felhasználót az IndexMoviesController osztály műveleti módszerére, amely megjeleníti a filmgyűjteményt, beleértve az imént végrehajtott módosításokat is.

Mielőtt az űrlapot közzétennénk a kiszolgálóra, az ügyféloldali ellenőrzés ellenőrzi a mezők érvényesítési szabályait. Ha ellenőrzési hibák történnek, hibaüzenet jelenik meg, és az űrlap nem lesz közzétéve. Ha a JavaScript le van tiltva, akkor nem fog ügyféloldali ellenőrzést alkalmazni, de a kiszolgáló észleli a nem érvényes közzétett értékeket, és az űrlapértékek hibaüzenetekkel jelennek meg. Az oktatóanyag későbbi részében részletesebben vizsgáljuk meg a modellérvényesítést . A nézetsablon Érvényesítési címke segédje gondoskodik a Views/Movies/Edit.cshtml megfelelő hibaüzenetek megjelenítéséről.

Szerkesztési nézet: Az abc helytelen árértékére vonatkozó kivétel azt állítja, hogy az Ár mezőnek számnak kell lennie. A xyz helytelen kiadási dátumértékére vonatkozó kivétel azt mondja, hogy Kérjük, adjon meg érvényes dátumot.

A filmvezérlő összes metódusa HttpGet hasonló mintát követ. Lekérnek egy mozgóképobjektumot (vagy objektumlistát, abban az esetben Index), és átadják az objektumot (modellt) a nézetnek. A Create metódus egy üres filmobjektumot ad át a Create nézetnek. Minden olyan metódus, amely adatokat hoz létre, szerkeszt, töröl vagy más módon módosít, a [HttpPost] metódus túlterhelése esetén ezt teszi. Egy metódus adatainak HTTP GET módosítása biztonsági kockázatot jelent. Az adatok metódusban HTTP GET való módosítása a HTTP ajánlott eljárásait és az architektúramintát REST is sérti, amely azt határozza meg, hogy a GET-kérések nem módosíthatják az alkalmazás állapotát. Más szóval a GET művelet végrehajtásának olyan biztonságos műveletnek kell lennie, amelynek nincsenek mellékhatásai, és nem módosítja a tárolt adatokat.

További erőforrások

Jól kezdtük a filmalkalmazást, de a bemutató nem ideális, például a ReleaseDate-nek két szónak kell lennie.

Index nézet: A kiadási dátum egy szó (szóköz nélkül), és minden film kiadási dátuma éjfélkor jelenik meg

Nyissa meg a Models/Movie.cs fájlt, és adja hozzá az alább látható kiemelt sorokat:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }

        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
    }
}

A DataAnnotationst a következő oktatóanyagban tárgyaljuk. A Megjelenítés attribútum határozza meg, hogy mit kell megjeleníteni egy mező nevének (ebben az esetben a "ReleaseDate" helyett a "ReleaseDate" értéket). A DataType attribútum megadja az adatok típusát (Dátum), így a mezőben tárolt időadatok nem jelennek meg.

Az [Column(TypeName = "decimal(18, 2)")] adatjegyzetre van szükség ahhoz, hogy az Entity Framework Core megfelelően le tudja képezni az Price-et az adatbázisban pénznemként. További információ: adattípusok.

Keresse meg a vezérlőt Movies , és tartsa lenyomva az egérmutatót egy Szerkesztés hivatkozás felett a cél URL-címének megtekintéséhez.

A böngészőablak látható, ahol az egér a Szerkesztés hivatkozáson van, és megjelenik egy hivatkozás URL-je: https://localhost:5001/Movies/Edit/5

A szerkesztési, részletes és törlési hivatkozásokat a fájl alapvető MVC horgonycímke-segédje Views/Movies/Index.cshtml hozza létre.

        <a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
        <a asp-action="Details" asp-route-id="@item.ID">Details</a> |
        <a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
    </td>
</tr>

A címkesegédek lehetővé teszik, hogy a kiszolgálóoldali kód részt vegyen a HTML-elemek Razor fájlokban történő létrehozásában és megjelenítésében. A fenti kódban a AnchorTagHelper HTML href attribútum értéke dinamikusan jön létre a vezérlő műveleti metódusa és az útvonalazonosító alapján. A Forrás megtekintése funkciót a kedvenc böngészőjében használhatja, vagy a fejlesztői eszközöket használva vizsgálhatja meg a létrehozott jelölést. A létrehozott HTML egy része az alábbiakban látható:

 <td>
    <a href="/Movies/Edit/4"> Edit </a> |
    <a href="/Movies/Details/4"> Details </a> |
    <a href="/Movies/Delete/4"> Delete </a>
</td>

A fájlban megadott útválasztási beállítás formátumának felidézése Startup.cs.

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

ASP.NET Core a https://localhost:5001/Movies/Edit/4 vezérlő Edit műveletmetódusára fordítja le a Movies-t, 4-es Id paraméterrel ellátva a kérést. (A vezérlőmetelyeket műveleti metódusnak is nevezik.)

A címkesegítőkről további információt a További erőforrások című témakörben talál.

Nyissa meg a vezérlőt Movies , és vizsgálja meg a két Edit műveleti módszert. Az alábbi kód azt a metódust HTTP GET Edit mutatja be, amely beolvassa a filmet, és feltölti a fájl által létrehozott szerkesztési Edit.cshtmlRazor űrlapot.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Az alábbi kód a HTTP POST Edit közzétett filmértékeket feldolgozó metódust mutatja be:

// POST: Movies/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (id != movie.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction("Index");
    }
    return View(movie);
}

Az [Bind] attribútum az egyik módja annak, hogy védelmet nyújtsunk a túlzott közzététel ellen. Kizárólag azokat a tulajdonságokat szabad beilleszteni a [Bind] attribútumba, amelyeket módosítani kíván. További információért lásd: A vezérlő túlterhelésével szembeni védelem. A ViewModels alternatív módszert kínál a túlküldés megelőzésére.

Figyelje meg, hogy a második Edit műveleti metódust az [HttpPost] attribútum előzi meg.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (id != movie.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az HttpPost attribútum azt határozza meg, hogy ez a Edit metódus kérések esetén POST hívható meg. Az attribútumot alkalmazhatja az [HttpGet] első szerkesztési módszerre, de ez nem szükséges, mert [HttpGet] ez az alapértelmezett érték.

Az ValidateAntiForgeryToken attribútum a kérések hamisításának megelőzésére szolgál, és a szerkesztési nézetfájlban (Views/Movies/Edit.cshtml) létrehozott antiforgery jogkivonattal van párosítva. A szerkesztési nézetfájl létrehozza az antiforgery jogkivonatot az űrlapcímke segédjével.

<form asp-action="Edit">

Az űrlapcímke-segéd létrehoz egy rejtett antiforgery tokent, amely meg kell egyeznie a [ValidateAntiForgeryToken] létrehozott antiforgery tokennel a Edit Filmek vezérlő metódusában. További információért lásd: Az ASP.NET Core alkalmazásban történő helyek közötti kéréshamisítás (XSRF/CSRF) elleni támadások megakadályozása.

A HttpGet Edit metódus felveszi a mozgókép ID paraméterét, megkeresi a filmet az Entity Framework FindAsync metódussal, és visszaadja a kijelölt filmet a Szerkesztés nézetbe. Ha nem található film, NotFound a rendszer a HTTP 404-et adja vissza.

// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie.FindAsync(id);
    if (movie == null)
    {
        return NotFound();
    }
    return View(movie);
}

Amikor az állványzatrendszer létrehozta a Szerkesztés nézetet, megvizsgálta az Movie osztályt, és kódot hozott létre az osztály minden tulajdonságához, hogy megjelenítse a <label> és <input> elemeket. Az alábbi példa a Visual Studio állványrendszer által létrehozott Szerkesztés nézetet mutatja be:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Id" />
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ReleaseDate" class="control-label"></label>
                <input asp-for="ReleaseDate" class="form-control" />
                <span asp-validation-for="ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Price" class="control-label"></label>
                <input asp-for="Price" class="form-control" />
                <span asp-validation-for="Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Figyelje meg, hogy a nézetsablonnak van egy @model MvcMovie.Models.Movie utasítása a fájl tetején. @model MvcMovie.Models.Movie azt határozza meg, hogy a nézet azt várja, hogy a nézetsablon típusa típus Movielegyen.

A sablonozott kód több Tag Helper metódust használ a HTML-jelölés egyszerűsítéséhez. A Címkecímke segéd megjeleníti a mező nevét ("Cím", "ReleaseDate", "Műfaj" vagy "Ár"). A beviteli címke súgója HTML-elemet <input> jelenít meg. Az Érvényesítési címke súgója megjeleníti az adott tulajdonsághoz társított érvényesítési üzeneteket.

Futtassa az alkalmazást, és keresse meg az /Movies URL-címet. Kattintson egy Szerkesztés hivatkozásra. A böngészőben tekintse meg a lap forrását. Az elemhez létrehozott HTML az <form> alábbiakban látható.

<form action="/Movies/Edit/7" method="post">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div class="text-danger" />
        <input type="hidden" data-val="true" data-val-required="The ID field is required." id="ID" name="ID" value="7" />
        <div class="form-group">
            <label class="control-label col-md-2" for="Genre" />
            <div class="col-md-10">
                <input class="form-control" type="text" id="Genre" name="Genre" value="Western" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="Price" />
            <div class="col-md-10">
                <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value="3.99" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
            </div>
        </div>
        <!-- Markup removed for brevity -->
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Inyxgp63fRFqUePGvuI5jGZsloJu1L7X9le1gy7NCIlSduCRx9jDQClrV9pOTTmqUyXnJBXhmrjcUVDJyDUMm7-MF_9rK8aAZdRdlOri7FmKVkRe_2v5LIHGKFcTjPrWPYnc9AdSbomkiOSaTEg7RU" />
</form>

Az <input> elemek olyan HTML <form> elemben találhatók, amelynek action attribútuma közzétételre az /Movies/Edit/id URL-címhez van beállítva. Az űrlapadatok a gombra kattintáskor lesznek közzétéve a Save kiszolgálón. A záró </form> elem előtti utolsó sor a XSRF rejtett token-t jeleníti meg, amelyet a Form Tag Helper generált.

A POST-kérelem feldolgozása

Az alábbi lista a [HttpPost] műveletmetódus Edit verzióját mutatja.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (id != movie.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(movie);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MovieExists(movie.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}

Az [ValidateAntiForgeryToken] attribútum ellenőrzi az űrlapcímke-segédben az antiforgery tokengenerátor által létrehozott rejtett XSRF-jogkivonatot

A modellkötési rendszer összegyűjti a közzétett űrlapértékeket, és létrehoz egy objektumot, amelyet Movie paraméterként ad át. A ModelState.IsValid tulajdonság ellenőrzi, hogy az űrlapon elküldött adatok felhasználhatók-e egy Movie objektum módosítására (szerkesztésére vagy frissítésére). Ha az adatai érvényesek, akkor azok a rendszer által lesznek mentve. A frissített (szerkesztett) filmadatokat az adatbáziskontekstus SaveChangesAsync metódusának meghívásával mentjük el az adatbázisba. Az adatok mentése után a kód átirányítja a felhasználót az IndexMoviesController osztály műveleti módszerére, amely megjeleníti a filmgyűjteményt, beleértve az imént végrehajtott módosításokat is.

Mielőtt az űrlapot közzétennénk a kiszolgálóra, az ügyféloldali ellenőrzés ellenőrzi a mezők érvényesítési szabályait. Ha ellenőrzési hibák történnek, hibaüzenet jelenik meg, és az űrlap nem lesz közzétéve. Ha a JavaScript le van tiltva, akkor nem fog ügyféloldali ellenőrzést alkalmazni, de a kiszolgáló észleli a nem érvényes közzétett értékeket, és az űrlapértékek hibaüzenetekkel jelennek meg. Az oktatóanyag későbbi részében részletesebben vizsgáljuk meg a modellérvényesítést . A nézetsablon Érvényesítési címke segédje gondoskodik a Views/Movies/Edit.cshtml megfelelő hibaüzenetek megjelenítéséről.

Szerkesztési nézet: Az abc helytelen árértékére vonatkozó kivétel azt állítja, hogy az Ár mezőnek számnak kell lennie. A xyz helytelen kiadási dátumértékére vonatkozó kivétel azt mondja, hogy Kérjük, adjon meg érvényes dátumot.

A filmvezérlő összes metódusa HttpGet hasonló mintát követ. Lekérnek egy mozgóképobjektumot (vagy objektumlistát, abban az esetben Index), és átadják az objektumot (modellt) a nézetnek. A Create metódus egy üres filmobjektumot ad át a Create nézetnek. Minden olyan metódus, amely adatokat hoz létre, szerkeszt, töröl vagy más módon módosít, a [HttpPost] metódus túlterhelése esetén ezt teszi. Egy metódus adatainak HTTP GET módosítása biztonsági kockázatot jelent. Az adatok metódusban HTTP GET való módosítása a HTTP ajánlott eljárásait és az architektúramintát REST is sérti, amely azt határozza meg, hogy a GET-kérések nem módosíthatják az alkalmazás állapotát. Más szóval a GET művelet végrehajtásának olyan biztonságos műveletnek kell lennie, amelynek nincsenek mellékhatásai, és nem módosítja a tárolt adatokat.

További erőforrások