Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Anmärkning
Det här är inte den senaste versionen av den här artikeln. Den aktuella versionen finns i .NET 10-versionen av den här artikeln.
Varning
Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i supportpolicyn för .NET och .NET Core. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .
Vi har en bra start på filmappen, men presentationen är inte idealisk, till exempel bör ReleaseDate vara två ord.
Models/Movie.cs Öppna filen och lägg till de markerade raderna som visas nedan:
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 förklaras i nästa handledning. Visningsattributet anger vad som ska visas för namnet på ett fält (i det här fallet "Utgivningsdatum" i stället för "ReleaseDate").
Attributet DataType anger typen av data (datum), så tidsinformationen som lagras i fältet visas inte.
Med hjälp av datakommentarerna ovan kör du programmet och uppdaterar /Movies sidan. Eftersom visningsmarkeringen använder metoderna @Html.DisplayNameFor och @Html.DisplayFor för att återge egenskapsnamnet och värdet, visar den uppdaterade Index vyn alla fält korrekt formaterade.
Versionsdatum är till exempel nu två ord och tidsinformationen visas inte längre.
Dataanteckningen [Column(TypeName = "decimal(18, 2)")] krävs för att Entity Framework Core kan mappa Price korrekt till valutan i databasen. Mer information finns i Datatyper.
Bläddra till kontrollanten Movies och håll muspekaren över en Redigera-länk för att se mål-URL:en.
Länkarna Redigera, Information och Ta bort genereras av Core MVC Anchor Tag Helper i Views/Movies/Index.cshtml filen.
<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>
Tagghjälpare gör det möjligt för kod på serversidan att delta i skapandet och återgivningen av HTML-element i Razor filer. I koden ovan AnchorTagHelper genererar html-attributvärdet href dynamiskt från kontrollantens åtgärdsmetod och routnings-ID. Du använder Visa källa från din favoritwebbläsare eller använder utvecklarverktygen för att undersöka den genererade markeringen. En del av den genererade HTML-koden visas nedan:
<td>
<a href="/Movies/Edit/4"> Edit </a> |
<a href="/Movies/Details/4"> Details </a> |
<a href="/Movies/Delete/4"> Delete </a>
</td>
Kom ihåg formatet för routningsuppsättningenProgram.cs i filen:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
ASP.NET Core översätter https://localhost:5001/Movies/Edit/4 till en begäran till Edit-metoden för Movies-kontrollern med parametern Id 4. (Kontrollantmetoder kallas även åtgärdsmetoder.)
Tag Helpers är en av de mest populära nya funktionerna i ASP.NET Core. Mer information finns i Ytterligare resurser.
Öppna kontrollanten Movies och granska de två Edit åtgärdsmetoderna. Följande kod visar HTTP GET Edit metoden som hämtar filmen och fyller i redigeringsformuläret Edit.cshtmlRazor som genereras av filen.
// 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);
}
Följande kod visar HTTP POST Edit metoden som bearbetar de publicerade filmvärdena:
// 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);
}
Attributet [Bind] är ett sätt att skydda mot överpublicering. Du bör bara inkludera egenskaper i det [Bind] attribut som du vill ändra. För mer information, se Skydda din kontrollenhet från överpublicering.
ViewModels tillhandahåller en alternativ metod för att förhindra överpublicering.
Observera att den andra Edit åtgärdsmetoden föregås av [HttpPost] attributet.
// 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);
}
Attributet HttpPost anger att den här Edit metoden endast kan anropas för POST begäranden. Du kan använda [HttpGet] attributet för den första redigeringsmetoden, men det är inte nödvändigt eftersom [HttpGet] är standardvärdet.
Attributet ValidateAntiForgeryToken används för att förhindra förfalskning av en begäran och paras ihop med en antiforgery-token som genereras i redigeringsvyfilen (Views/Movies/Edit.cshtml). Filen för redigeringsvy genererar antiforgery-token med hjälp av Form Tag Helper.
<form asp-action="Edit">
Hjälpverktyget för formulärtagg genererar en dold antiforgery-token som måste matcha den [ValidateAntiForgeryToken] genererade antiforgery-token i Edit metoden för kontrollanten Filmer. Mer information finns i Förhindra XSRF-/CSRF-attacker (Cross-Site Request Forgery) i ASP.NET Core.
Metoden HttpGet Edit tar filmparametern ID , letar upp filmen med entity framework-metoden FindAsync och returnerar den valda filmen till redigeringsvyn. Om en film inte kan hittas returneras NotFound (HTTP 404).
// 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);
}
När scaffoldingsystemet skapade vyn Redigera undersökte klassen Movie och skapade kod för att rendera <label> och <input> element för varje egenskap i klassen. I följande exempel visas redigeringsvyn som genererades av Visual Studio-scaffolding-systemet:
@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");}
}
Observera hur vymallen har en @model MvcMovie.Models.Movie -instruktion överst i filen.
@model MvcMovie.Models.Movie anger att vyn förväntar sig att modellen för visningsmallen ska vara av typen Movie.
Denna genererade kodstruktur använder flera Tag Helper-metoder för att effektivisera HTML-kod.
Etikett Tagghjälpen visar fältnamnet ("Rubrik", "Utgivningsdatum", "Genre" eller "Pris").
Hjälpverktyget för indatataggen återger ett HTML-element<input>.
Hjälpen för verifieringstaggen visar alla valideringsmeddelanden som är associerade med den egenskapen.
Kör programmet och navigera till /Movies URL:en. Klicka på länken Redigera . I webbläsaren visar du källan för sidan. Den genererade HTML-koden för elementet <form> visas nedan.
<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>
Elementen <input> finns i ett HTML <form> element vars action attribut är inställt på att skickas till /Movies/Edit/id URL:en. Formulärdata publiceras på servern när Save knappen klickas. Den sista raden före det avslutande </form> elementet visar den dolda XSRF-token som genererats av hjälpverktyget för formulärtagg.
Bearbeta POST-begäran
Följande lista visar [HttpPost] versionen av Edit åtgärdsmetoden.
// 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);
}
Attributet [ValidateAntiForgeryToken] verifierar den dolda XSRF-token som genereras av generatorn för antiforgery-token i Form Tag Helper
Modellbindningssystemet tar de postade formulärvärdena och skapar ett Movie-objekt som skickas som movie-parametern. Egenskapen ModelState.IsValid verifierar att data som skickas i formuläret kan användas för att ändra (redigera eller uppdatera) ett Movie objekt. Om data är giltiga sparas de. Uppdaterade (redigerade) filmdata sparas i databasen genom att anropa SaveChangesAsync metoden för databaskontext. När du har sparat data omdirigerar koden användaren till Index åtgärdsmetoden för MoviesController klassen, som visar filmsamlingen, inklusive de ändringar som just har gjorts.
Innan formuläret publiceras på servern kontrollerar verifieringen på klientsidan eventuella verifieringsregler i fälten. Om det finns några verifieringsfel visas ett felmeddelande och formuläret publiceras inte. Om JavaScript är inaktiverat har du ingen validering på klientsidan, men servern identifierar de skickade värdena som inte är giltiga och formulärvärdena kommer att visas igen med felmeddelanden. Senare i självstudien undersöker vi modellverifiering mer detaljerat.
Hjälpverktyget för verifieringstaggen i visningsmallen Views/Movies/Edit.cshtml tar hand om att visa lämpliga felmeddelanden.
HttpGet Alla metoder i filmkontrollanten följer ett liknande mönster. De hämtar ett filmobjekt (eller en lista med objekt, i fallet Index) och skickar objektet (modellen) till vyn. Metoden Create skickar ett tomt filmobjekt till Create vy. Alla metoder som skapar, redigerar, tar bort eller på annat sätt ändrar data gör det i [HttpPost] metodens överlagring. Att ändra data i en HTTP GET metod är en säkerhetsrisk. Att ändra data i en HTTP GET metod strider också mot HTTP-metodtipsen och arkitekturmönstret REST , vilket anger att GET-begäranden inte ska ändra programmets tillstånd. Med andra ord bör det vara en säker åtgärd att utföra en GET-åtgärd som inte har några biverkningar och inte ändrar dina bevarade data.
Ytterligare resurser
- Globalisering och lokalisering
- Introduktion till Tag Helpers
- Författarens Tag-hjälpare
- Förhindra XSRF-/CSRF-attacker (Cross-Site Request Forgery) i ASP.NET Core
- Skydda kontrollenheten från överpublicering
- ViewModels
- Formulärtagghjälpare
- Hjälp för indatatagg
- Etiketttaggshjälpare
- Välj Tag Helper
- Hjälp om verifieringstaggen
Vi har en bra start på filmappen, men presentationen är inte idealisk, till exempel bör ReleaseDate vara två ord.
Models/Movie.cs Öppna filen och lägg till de markerade raderna som visas nedan:
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 förklaras i nästa handledning. Visningsattributet anger vad som ska visas för namnet på ett fält (i det här fallet "Utgivningsdatum" i stället för "ReleaseDate").
Attributet DataType anger typen av data (datum), så tidsinformationen som lagras i fältet visas inte.
Dataanteckningen [Column(TypeName = "decimal(18, 2)")] krävs för att Entity Framework Core kan mappa Price korrekt till valutan i databasen. Mer information finns i Datatyper.
Bläddra till kontrollanten Movies och håll muspekaren över en Redigera-länk för att se mål-URL:en.
Länkarna Redigera, Information och Ta bort genereras av Core MVC Anchor Tag Helper i Views/Movies/Index.cshtml filen.
<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>
Tagghjälpare gör det möjligt för kod på serversidan att delta i skapandet och återgivningen av HTML-element i Razor filer. I koden ovan AnchorTagHelper genererar html-attributvärdet href dynamiskt från kontrollantens åtgärdsmetod och routnings-ID. Du använder Visa källa från din favoritwebbläsare eller använder utvecklarverktygen för att undersöka den genererade markeringen. En del av den genererade HTML-koden visas nedan:
<td>
<a href="/Movies/Edit/4"> Edit </a> |
<a href="/Movies/Details/4"> Details </a> |
<a href="/Movies/Delete/4"> Delete </a>
</td>
Kom ihåg formatet för routningsuppsättningenProgram.cs i filen:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
ASP.NET Core översätter https://localhost:5001/Movies/Edit/4 till en begäran till Edit-metoden för Movies-kontrollern med parametern Id 4. (Kontrollantmetoder kallas även åtgärdsmetoder.)
Tag Helpers är en av de mest populära nya funktionerna i ASP.NET Core. Mer information finns i Ytterligare resurser.
Öppna kontrollanten Movies och granska de två Edit åtgärdsmetoderna. Följande kod visar HTTP GET Edit metoden som hämtar filmen och fyller i redigeringsformuläret Edit.cshtmlRazor som genereras av filen.
// 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);
}
Följande kod visar HTTP POST Edit metoden som bearbetar de publicerade filmvärdena:
// 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);
}
Attributet [Bind] är ett sätt att skydda mot överpublicering. Du bör bara inkludera egenskaper i det [Bind] attribut som du vill ändra. För mer information, se Skydda din kontrollenhet från överpublicering.
ViewModels tillhandahåller en alternativ metod för att förhindra överpublicering.
Observera att den andra Edit åtgärdsmetoden föregås av [HttpPost] attributet.
// 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);
}
Attributet HttpPost anger att den här Edit metoden endast kan anropas för POST begäranden. Du kan använda [HttpGet] attributet för den första redigeringsmetoden, men det är inte nödvändigt eftersom [HttpGet] är standardvärdet.
Attributet ValidateAntiForgeryToken används för att förhindra förfalskning av en begäran och paras ihop med en antiforgery-token som genereras i redigeringsvyfilen (Views/Movies/Edit.cshtml). Filen för redigeringsvy genererar antiforgery-token med hjälp av Form Tag Helper.
<form asp-action="Edit">
Hjälpverktyget för formulärtagg genererar en dold antiforgery-token som måste matcha den [ValidateAntiForgeryToken] genererade antiforgery-token i Edit metoden för kontrollanten Filmer. Mer information finns i Förhindra XSRF-/CSRF-attacker (Cross-Site Request Forgery) i ASP.NET Core.
Metoden HttpGet Edit tar filmparametern ID , letar upp filmen med entity framework-metoden FindAsync och returnerar den valda filmen till redigeringsvyn. Om en film inte kan hittas returneras NotFound (HTTP 404).
// 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);
}
När scaffoldingsystemet skapade vyn Redigera undersökte klassen Movie och skapade kod för att rendera <label> och <input> element för varje egenskap i klassen. I följande exempel visas redigeringsvyn som genererades av Visual Studio-scaffolding-systemet:
@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");}
}
Observera hur vymallen har en @model MvcMovie.Models.Movie -instruktion överst i filen.
@model MvcMovie.Models.Movie anger att vyn förväntar sig att modellen för visningsmallen ska vara av typen Movie.
Denna genererade kodstruktur använder flera Tag Helper-metoder för att effektivisera HTML-kod.
Etikett Tagghjälpen visar fältnamnet ("Rubrik", "Utgivningsdatum", "Genre" eller "Pris").
Hjälpverktyget för indatataggen återger ett HTML-element<input>.
Hjälpen för verifieringstaggen visar alla valideringsmeddelanden som är associerade med den egenskapen.
Kör programmet och navigera till /Movies URL:en. Klicka på länken Redigera . I webbläsaren visar du källan för sidan. Den genererade HTML-koden för elementet <form> visas nedan.
<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>
Elementen <input> finns i ett HTML <form> element vars action attribut är inställt på att skickas till /Movies/Edit/id URL:en. Formulärdata publiceras på servern när Save knappen klickas. Den sista raden före det avslutande </form> elementet visar den dolda XSRF-token som genererats av hjälpverktyget för formulärtagg.
Bearbeta POST-begäran
Följande lista visar [HttpPost] versionen av Edit åtgärdsmetoden.
// 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);
}
Attributet [ValidateAntiForgeryToken] verifierar den dolda XSRF-token som genereras av generatorn för antiforgery-token i Form Tag Helper
Modellbindningssystemet tar de postade formulärvärdena och skapar ett Movie-objekt som skickas som movie-parametern. Egenskapen ModelState.IsValid verifierar att data som skickas i formuläret kan användas för att ändra (redigera eller uppdatera) ett Movie objekt. Om data är giltiga sparas de. Uppdaterade (redigerade) filmdata sparas i databasen genom att anropa SaveChangesAsync metoden för databaskontext. När du har sparat data omdirigerar koden användaren till Index åtgärdsmetoden för MoviesController klassen, som visar filmsamlingen, inklusive de ändringar som just har gjorts.
Innan formuläret publiceras på servern kontrollerar verifieringen på klientsidan eventuella verifieringsregler i fälten. Om det finns några verifieringsfel visas ett felmeddelande och formuläret publiceras inte. Om JavaScript är inaktiverat har du ingen validering på klientsidan, men servern identifierar de skickade värdena som inte är giltiga och formulärvärdena kommer att visas igen med felmeddelanden. Senare i självstudien undersöker vi modellverifiering mer detaljerat.
Hjälpverktyget för verifieringstaggen i visningsmallen Views/Movies/Edit.cshtml tar hand om att visa lämpliga felmeddelanden.
HttpGet Alla metoder i filmkontrollanten följer ett liknande mönster. De hämtar ett filmobjekt (eller en lista med objekt, i fallet Index) och skickar objektet (modellen) till vyn. Metoden Create skickar ett tomt filmobjekt till Create vy. Alla metoder som skapar, redigerar, tar bort eller på annat sätt ändrar data gör det i [HttpPost] metodens överlagring. Att ändra data i en HTTP GET metod är en säkerhetsrisk. Att ändra data i en HTTP GET metod strider också mot HTTP-metodtipsen och arkitekturmönstret REST , vilket anger att GET-begäranden inte ska ändra programmets tillstånd. Med andra ord bör det vara en säker åtgärd att utföra en GET-åtgärd som inte har några biverkningar och inte ändrar dina bevarade data.
Ytterligare resurser
- Globalisering och lokalisering
- Introduktion till Tag Helpers
- Författarens Tag-hjälpare
- Förhindra XSRF-/CSRF-attacker (Cross-Site Request Forgery) i ASP.NET Core
- Skydda kontrollenheten från överpublicering
- ViewModels
- Formulärtagghjälpare
- Hjälp för indatatagg
- Etiketttagghjälpare
- Välj Tag Helper
- Hjälp om verifieringstaggen
Vi har en bra start på filmappen, men presentationen är inte idealisk, till exempel bör ReleaseDate vara två ord.
Models/Movie.cs Öppna filen och lägg till de markerade raderna som visas nedan:
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 förklaras i nästa handledning. Visningsattributet anger vad som ska visas för namnet på ett fält (i det här fallet "Utgivningsdatum" i stället för "ReleaseDate").
Attributet DataType anger typen av data (datum), så tidsinformationen som lagras i fältet visas inte.
Dataanteckningen [Column(TypeName = "decimal(18, 2)")] krävs för att Entity Framework Core kan mappa Price korrekt till valutan i databasen. Mer information finns i Datatyper.
Bläddra till kontrollanten Movies och håll muspekaren över en Redigera-länk för att se mål-URL:en.
Länkarna Redigera, Information och Ta bort genereras av Core MVC Anchor Tag Helper i Views/Movies/Index.cshtml filen.
<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>
Tagghjälpare gör det möjligt för kod på serversidan att delta i skapandet och återgivningen av HTML-element i Razor filer. I koden ovan AnchorTagHelper genererar html-attributvärdet href dynamiskt från kontrollantens åtgärdsmetod och routnings-ID. Du använder Visa källa från din favoritwebbläsare eller använder utvecklarverktygen för att undersöka den genererade markeringen. En del av den genererade HTML-koden visas nedan:
<td>
<a href="/Movies/Edit/4"> Edit </a> |
<a href="/Movies/Details/4"> Details </a> |
<a href="/Movies/Delete/4"> Delete </a>
</td>
Kom ihåg formatet för routningsuppsättningenProgram.cs i filen:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
ASP.NET Core översätter https://localhost:5001/Movies/Edit/4 till en begäran till Edit-metoden för Movies-kontrollern med parametern Id 4. (Kontrollantmetoder kallas även åtgärdsmetoder.)
Tag Helpers är en av de mest populära nya funktionerna i ASP.NET Core. Mer information finns i Ytterligare resurser.
Öppna kontrollanten Movies och granska de två Edit åtgärdsmetoderna. Följande kod visar HTTP GET Edit metoden som hämtar filmen och fyller i redigeringsformuläret Edit.cshtmlRazor som genereras av filen.
// 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);
}
Följande kod visar HTTP POST Edit metoden som bearbetar de publicerade filmvärdena:
// 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);
}
Attributet [Bind] är ett sätt att skydda mot överpublicering. Du bör bara inkludera egenskaper i det [Bind] attribut som du vill ändra. För mer information, se Skydda din kontrollenhet från överpublicering.
ViewModels tillhandahåller en alternativ metod för att förhindra överpublicering.
Observera att den andra Edit åtgärdsmetoden föregås av [HttpPost] attributet.
// 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);
}
Attributet HttpPost anger att den här Edit metoden endast kan anropas för POST begäranden. Du kan använda [HttpGet] attributet för den första redigeringsmetoden, men det är inte nödvändigt eftersom [HttpGet] är standardvärdet.
Attributet ValidateAntiForgeryToken används för att förhindra förfalskning av en begäran och paras ihop med en antiforgery-token som genereras i redigeringsvyfilen (Views/Movies/Edit.cshtml). Filen för redigeringsvy genererar antiforgery-token med hjälp av Form Tag Helper.
<form asp-action="Edit">
Hjälpverktyget för formulärtagg genererar en dold antiforgery-token som måste matcha den [ValidateAntiForgeryToken] genererade antiforgery-token i Edit metoden för kontrollanten Filmer. Mer information finns i Förhindra XSRF-/CSRF-attacker (Cross-Site Request Forgery) i ASP.NET Core.
Metoden HttpGet Edit tar filmparametern ID , letar upp filmen med entity framework-metoden FindAsync och returnerar den valda filmen till redigeringsvyn. Om en film inte kan hittas returneras NotFound (HTTP 404).
// 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);
}
När scaffoldingsystemet skapade vyn Redigera undersökte klassen Movie och skapade kod för att rendera <label> och <input> element för varje egenskap i klassen. I följande exempel visas redigeringsvyn som genererades av Visual Studio-scaffolding-systemet:
@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");}
}
Observera hur vymallen har en @model MvcMovie.Models.Movie -instruktion överst i filen.
@model MvcMovie.Models.Movie anger att vyn förväntar sig att modellen för visningsmallen ska vara av typen Movie.
Denna genererade kodstruktur använder flera Tag Helper-metoder för att effektivisera HTML-kod.
Etikett Tagghjälpen visar fältnamnet ("Rubrik", "Utgivningsdatum", "Genre" eller "Pris").
Hjälpverktyget för indatataggen återger ett HTML-element<input>.
Hjälpen för verifieringstaggen visar alla valideringsmeddelanden som är associerade med den egenskapen.
Kör programmet och navigera till /Movies URL:en. Klicka på länken Redigera . I webbläsaren visar du källan för sidan. Den genererade HTML-koden för elementet <form> visas nedan.
<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>
Elementen <input> finns i ett HTML <form> element vars action attribut är inställt på att skickas till /Movies/Edit/id URL:en. Formulärdata publiceras på servern när Save knappen klickas. Den sista raden före det avslutande </form> elementet visar den dolda XSRF-token som genererats av hjälpverktyget för formulärtagg.
Bearbeta POST-begäran
Följande lista visar [HttpPost] versionen av Edit åtgärdsmetoden.
// 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);
}
Attributet [ValidateAntiForgeryToken] verifierar den dolda XSRF-token som genereras av generatorn för antiforgery-token i Form Tag Helper
Modellbindningssystemet tar de postade formulärvärdena och skapar ett Movie-objekt som skickas som movie-parametern. Egenskapen ModelState.IsValid verifierar att data som skickas i formuläret kan användas för att ändra (redigera eller uppdatera) ett Movie objekt. Om data är giltiga sparas de. Uppdaterade (redigerade) filmdata sparas i databasen genom att anropa SaveChangesAsync metoden för databaskontext. När du har sparat data omdirigerar koden användaren till Index åtgärdsmetoden för MoviesController klassen, som visar filmsamlingen, inklusive de ändringar som just har gjorts.
Innan formuläret publiceras på servern kontrollerar verifieringen på klientsidan eventuella verifieringsregler i fälten. Om det finns några verifieringsfel visas ett felmeddelande och formuläret publiceras inte. Om JavaScript är inaktiverat har du ingen validering på klientsidan, men servern identifierar de skickade värdena som inte är giltiga och formulärvärdena kommer att visas igen med felmeddelanden. Senare i självstudien undersöker vi modellverifiering mer detaljerat.
Hjälpverktyget för verifieringstaggen i visningsmallen Views/Movies/Edit.cshtml tar hand om att visa lämpliga felmeddelanden.
HttpGet Alla metoder i filmkontrollanten följer ett liknande mönster. De hämtar ett filmobjekt (eller en lista med objekt, i fallet Index) och skickar objektet (modellen) till vyn. Metoden Create skickar ett tomt filmobjekt till Create vy. Alla metoder som skapar, redigerar, tar bort eller på annat sätt ändrar data gör det i [HttpPost] metodens överlagring. Att ändra data i en HTTP GET metod är en säkerhetsrisk. Att ändra data i en HTTP GET metod strider också mot HTTP-metodtipsen och arkitekturmönstret REST , vilket anger att GET-begäranden inte ska ändra programmets tillstånd. Med andra ord bör det vara en säker åtgärd att utföra en GET-åtgärd som inte har några biverkningar och inte ändrar dina bevarade data.
Ytterligare resurser
- Globalisering och lokalisering
- Introduktion till Tag Helpers
- Författarens Tag-hjälpare
- Förhindra XSRF-/CSRF-attacker (Cross-Site Request Forgery) i ASP.NET Core
- Skydda kontrollenheten från överpublicering
- ViewModels
- Formulärtagghjälpare
- Hjälp för indatatagg
- Etiketttaggshjälpare
- Välj Tag Helper
- Hjälp om verifieringstaggen
Vi har en bra start på filmappen, men presentationen är inte idealisk, till exempel bör ReleaseDate vara två ord.
Models/Movie.cs Öppna filen och lägg till de markerade raderna som visas nedan:
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 förklaras i nästa handledning. Visningsattributet anger vad som ska visas för namnet på ett fält (i det här fallet "Utgivningsdatum" i stället för "ReleaseDate").
Attributet DataType anger typen av data (datum), så tidsinformationen som lagras i fältet visas inte.
Dataanteckningen [Column(TypeName = "decimal(18, 2)")] krävs för att Entity Framework Core kan mappa Price korrekt till valutan i databasen. Mer information finns i Datatyper.
Bläddra till kontrollanten Movies och håll muspekaren över en Redigera-länk för att se mål-URL:en.
Länkarna Redigera, Information och Ta bort genereras av Core MVC Anchor Tag Helper i Views/Movies/Index.cshtml filen.
<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>
Tagghjälpare gör det möjligt för kod på serversidan att delta i skapandet och återgivningen av HTML-element i Razor filer. I koden ovan AnchorTagHelper genererar html-attributvärdet href dynamiskt från kontrollantens åtgärdsmetod och routnings-ID. Du använder Visa källa från din favoritwebbläsare eller använder utvecklarverktygen för att undersöka den genererade markeringen. En del av den genererade HTML-koden visas nedan:
<td>
<a href="/Movies/Edit/4"> Edit </a> |
<a href="/Movies/Details/4"> Details </a> |
<a href="/Movies/Delete/4"> Delete </a>
</td>
Kom ihåg formatet för routningsuppsättningenProgram.cs i filen:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
ASP.NET Core översätter https://localhost:5001/Movies/Edit/4 till en begäran till Edit-metoden för Movies-kontrollern med parametern Id 4. (Kontrollantmetoder kallas även åtgärdsmetoder.)
Tag Helpers är en populär funktion i ASP.NET Core. Mer information om dem finns i Ytterligare resurser.
Öppna kontrollanten Movies och granska de två Edit åtgärdsmetoderna. Följande kod visar HTTP GET Edit metoden som hämtar filmen och fyller i redigeringsformuläret Edit.cshtmlRazor som genereras av filen.
// 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);
}
Följande kod visar HTTP POST Edit metoden som bearbetar de publicerade filmvärdena:
// 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);
}
Attributet [Bind] är ett sätt att skydda mot överpublicering. Du bör bara inkludera egenskaper i det [Bind] attribut som du vill ändra. För mer information, se Skydda din kontrollenhet från överpublicering.
ViewModels tillhandahåller en alternativ metod för att förhindra överpublicering.
Observera att den andra Edit åtgärdsmetoden föregås av [HttpPost] attributet.
// 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);
}
Attributet HttpPost anger att den här Edit metoden endast kan anropas för POST begäranden. Du kan använda [HttpGet] attributet för den första redigeringsmetoden, men det är inte nödvändigt eftersom [HttpGet] är standardvärdet.
Attributet ValidateAntiForgeryToken används för att förhindra förfalskning av en begäran och paras ihop med en antiforgery-token som genereras i redigeringsvyfilen (Views/Movies/Edit.cshtml). Filen för redigeringsvy genererar antiforgery-token med hjälp av Form Tag Helper.
<form asp-action="Edit">
Hjälpverktyget för formulärtagg genererar en dold antiforgery-token som måste matcha den [ValidateAntiForgeryToken] genererade antiforgery-token i Edit metoden för kontrollanten Filmer. Mer information finns i Förhindra XSRF-/CSRF-attacker (Cross-Site Request Forgery) i ASP.NET Core.
Metoden HttpGet Edit tar filmparametern ID , letar upp filmen med entity framework-metoden FindAsync och returnerar den valda filmen till redigeringsvyn. Om en film inte kan hittas returneras NotFound (HTTP 404).
// 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);
}
När scaffoldingsystemet skapade vyn Redigera undersökte klassen Movie och skapade kod för att rendera <label> och <input> element för varje egenskap i klassen. I följande exempel visas redigeringsvyn som genererades av Visual Studio-scaffolding-systemet:
@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");}
}
Observera hur vymallen har en @model MvcMovie.Models.Movie -instruktion överst i filen.
@model MvcMovie.Models.Movie anger att vyn förväntar sig att modellen för visningsmallen ska vara av typen Movie.
Denna genererade kodstruktur använder flera Tag Helper-metoder för att effektivisera HTML-kod.
Etikett Tagghjälpen visar fältnamnet ("Rubrik", "Utgivningsdatum", "Genre" eller "Pris").
Hjälpverktyget för indatataggen återger ett HTML-element<input>.
Hjälpen för verifieringstaggen visar alla valideringsmeddelanden som är associerade med den egenskapen.
Kör programmet och navigera till /Movies URL:en. Klicka på länken Redigera . I webbläsaren visar du källan för sidan. Den genererade HTML-koden för elementet <form> visas nedan.
<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>
Elementen <input> finns i ett HTML <form> element vars action attribut är inställt på att skickas till /Movies/Edit/id URL:en. Formulärdata publiceras på servern när Save knappen klickas. Den sista raden före det avslutande </form> elementet visar den dolda XSRF-token som genererats av hjälpverktyget för formulärtagg.
Bearbeta POST-begäran
Följande lista visar [HttpPost] versionen av Edit åtgärdsmetoden.
// 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);
}
Attributet [ValidateAntiForgeryToken] verifierar den dolda XSRF-token som genereras av generatorn för antiforgery-token i Form Tag Helper
Modellbindningssystemet tar de postade formulärvärdena och skapar ett Movie-objekt som skickas som movie-parametern. Egenskapen ModelState.IsValid verifierar att data som skickas i formuläret kan användas för att ändra (redigera eller uppdatera) ett Movie objekt. Om data är giltiga sparas de. Uppdaterade (redigerade) filmdata sparas i databasen genom att anropa SaveChangesAsync metoden för databaskontext. När du har sparat data omdirigerar koden användaren till Index åtgärdsmetoden för MoviesController klassen, som visar filmsamlingen, inklusive de ändringar som just har gjorts.
Innan formuläret publiceras på servern kontrollerar verifieringen på klientsidan eventuella verifieringsregler i fälten. Om det finns några verifieringsfel visas ett felmeddelande och formuläret publiceras inte. Om JavaScript är inaktiverat har du ingen validering på klientsidan, men servern identifierar de skickade värdena som inte är giltiga och formulärvärdena kommer att visas igen med felmeddelanden. Senare i självstudien undersöker vi modellverifiering mer detaljerat.
Hjälpverktyget för verifieringstaggen i visningsmallen Views/Movies/Edit.cshtml tar hand om att visa lämpliga felmeddelanden.
HttpGet Alla metoder i filmkontrollanten följer ett liknande mönster. De hämtar ett filmobjekt (eller en lista med objekt, i fallet Index) och skickar objektet (modellen) till vyn. Metoden Create skickar ett tomt filmobjekt till Create vy. Alla metoder som skapar, redigerar, tar bort eller på annat sätt ändrar data gör det i [HttpPost] metodens överlagring. Att ändra data i en HTTP GET metod är en säkerhetsrisk. Att ändra data i en HTTP GET metod strider också mot HTTP-metodtipsen och arkitekturmönstret REST , vilket anger att GET-begäranden inte ska ändra programmets tillstånd. Med andra ord bör det vara en säker åtgärd att utföra en GET-åtgärd som inte har några biverkningar och inte ändrar dina bevarade data.
Ytterligare resurser
- Globalisering och lokalisering
- Introduktion till Tag Helpers
- Författarens Tag-hjälpare
- Förhindra XSRF-/CSRF-attacker (Cross-Site Request Forgery) i ASP.NET Core
- Skydda kontrollenheten från överpublicering
- ViewModels
- Formulärtagghjälpare
- Hjälp för indatatagg
- Etiketttagghjälpare
- Välj Tag Helper
- Hjälp om verifieringstaggen
Vi har en bra start på filmappen, men presentationen är inte idealisk, till exempel bör ReleaseDate vara två ord.
Models/Movie.cs Öppna filen och lägg till de markerade raderna som visas nedan:
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; }
}
}
Vi går igenom DataAnnotations i nästa handledning. Visningsattributet anger vad som ska visas för namnet på ett fält (i det här fallet "Utgivningsdatum" i stället för "ReleaseDate"). Attributet DataType anger typen av data (datum), så tidsinformationen som lagras i fältet visas inte.
Dataanteckningen [Column(TypeName = "decimal(18, 2)")] krävs för att Entity Framework Core kan mappa Price korrekt till valutan i databasen. Mer information finns i Datatyper.
Bläddra till kontrollanten Movies och håll muspekaren över en Redigera-länk för att se mål-URL:en.
Länkarna Redigera, Information och Ta bort genereras av Core MVC Anchor Tag Helper i Views/Movies/Index.cshtml filen.
<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>
Tagghjälpare gör det möjligt för kod på serversidan att delta i skapandet och återgivningen av HTML-element i Razor filer. I koden ovan AnchorTagHelper genererar html-attributvärdet href dynamiskt från kontrollantens åtgärdsmetod och routnings-ID. Du använder Visa källa från din favoritwebbläsare eller använder utvecklarverktygen för att undersöka den genererade markeringen. En del av den genererade HTML-koden visas nedan:
<td>
<a href="/Movies/Edit/4"> Edit </a> |
<a href="/Movies/Details/4"> Details </a> |
<a href="/Movies/Delete/4"> Delete </a>
</td>
Kom ihåg formatet för routningsuppsättningenStartup.cs i filen:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
ASP.NET Core översätter https://localhost:5001/Movies/Edit/4 till en begäran till Edit-metoden för Movies-kontrollern med parametern Id 4. (Kontrollantmetoder kallas även åtgärdsmetoder.)
Mer information om Tag Helpers finnsi Ytterligare resurser.
Öppna kontrollanten Movies och granska de två Edit åtgärdsmetoderna. Följande kod visar HTTP GET Edit metoden som hämtar filmen och fyller i redigeringsformuläret Edit.cshtmlRazor som genereras av filen.
// 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);
}
Följande kod visar HTTP POST Edit metoden som bearbetar de publicerade filmvärdena:
// 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);
}
Attributet [Bind] är ett sätt att skydda mot överpublicering. Du bör bara inkludera egenskaper i det [Bind] attribut som du vill ändra. För mer information, se Skydda din kontrollenhet från överpublicering.
ViewModels tillhandahåller en alternativ metod för att förhindra överpublicering.
Observera att den andra Edit åtgärdsmetoden föregås av [HttpPost] attributet.
[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);
}
Attributet HttpPost anger att den här Edit metoden endast kan anropas för POST begäranden. Du kan använda [HttpGet] attributet för den första redigeringsmetoden, men det är inte nödvändigt eftersom [HttpGet] är standardvärdet.
Attributet ValidateAntiForgeryToken används för att förhindra förfalskning av en begäran och paras ihop med en antiforgery-token som genereras i redigeringsvyfilen (Views/Movies/Edit.cshtml). Filen för redigeringsvy genererar antiforgery-token med hjälp av Form Tag Helper.
<form asp-action="Edit">
Hjälpverktyget för formulärtagg genererar en dold antiforgery-token som måste matcha den [ValidateAntiForgeryToken] genererade antiforgery-token i Edit metoden för kontrollanten Filmer. Mer information finns i Förhindra XSRF-/CSRF-attacker (Cross-Site Request Forgery) i ASP.NET Core.
Metoden HttpGet Edit tar filmparametern ID , letar upp filmen med entity framework-metoden FindAsync och returnerar den valda filmen till redigeringsvyn. Om en film inte kan hittas returneras NotFound (HTTP 404).
// 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);
}
När scaffoldingsystemet skapade vyn Redigera undersökte klassen Movie och skapade kod för att rendera <label> och <input> element för varje egenskap i klassen. I följande exempel visas redigeringsvyn som genererades av Visual Studio-scaffolding-systemet:
@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");}
}
Observera hur vymallen har en @model MvcMovie.Models.Movie -instruktion överst i filen.
@model MvcMovie.Models.Movie anger att vyn förväntar sig att modellen för visningsmallen ska vara av typen Movie.
Denna genererade kodstruktur använder flera Tag Helper-metoder för att effektivisera HTML-kod.
Etikett Tagghjälpen visar fältnamnet ("Rubrik", "Utgivningsdatum", "Genre" eller "Pris").
Hjälpverktyget för indatataggen återger ett HTML-element<input>.
Hjälpen för verifieringstaggen visar alla valideringsmeddelanden som är associerade med den egenskapen.
Kör programmet och navigera till /Movies URL:en. Klicka på länken Redigera . I webbläsaren visar du källan för sidan. Den genererade HTML-koden för elementet <form> visas nedan.
<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>
Elementen <input> finns i ett HTML <form> element vars action attribut är inställt på att skickas till /Movies/Edit/id URL:en. Formulärdata publiceras på servern när Save knappen klickas. Den sista raden före det avslutande </form> elementet visar den dolda XSRF-token som genererats av hjälpverktyget för formulärtagg.
Bearbeta POST-begäran
Följande lista visar [HttpPost] versionen av Edit åtgärdsmetoden.
[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);
}
Attributet [ValidateAntiForgeryToken] verifierar den dolda XSRF-token som genereras av generatorn för antiforgery-token i Form Tag Helper
Modellbindningssystemet tar de postade formulärvärdena och skapar ett Movie-objekt som skickas som movie-parametern. Egenskapen ModelState.IsValid verifierar att data som skickas i formuläret kan användas för att ändra (redigera eller uppdatera) ett Movie objekt. Om data är giltiga sparas de. Uppdaterade (redigerade) filmdata sparas i databasen genom att anropa SaveChangesAsync metoden för databaskontext. När du har sparat data omdirigerar koden användaren till Index åtgärdsmetoden för MoviesController klassen, som visar filmsamlingen, inklusive de ändringar som just har gjorts.
Innan formuläret publiceras på servern kontrollerar verifieringen på klientsidan eventuella verifieringsregler i fälten. Om det finns några verifieringsfel visas ett felmeddelande och formuläret publiceras inte. Om JavaScript är inaktiverat har du ingen validering på klientsidan, men servern identifierar de skickade värdena som inte är giltiga och formulärvärdena kommer att visas igen med felmeddelanden. Senare i självstudien undersöker vi modellverifiering mer detaljerat.
Hjälpverktyget för verifieringstaggen i visningsmallen Views/Movies/Edit.cshtml tar hand om att visa lämpliga felmeddelanden.
HttpGet Alla metoder i filmkontrollanten följer ett liknande mönster. De hämtar ett filmobjekt (eller en lista med objekt, i fallet Index) och skickar objektet (modellen) till vyn. Metoden Create skickar ett tomt filmobjekt till Create vy. Alla metoder som skapar, redigerar, tar bort eller på annat sätt ändrar data gör det i [HttpPost] metodens överlagring. Att ändra data i en HTTP GET metod är en säkerhetsrisk. Att ändra data i en HTTP GET metod strider också mot HTTP-metodtipsen och arkitekturmönstret REST , vilket anger att GET-begäranden inte ska ändra programmets tillstånd. Med andra ord bör det vara en säker åtgärd att utföra en GET-åtgärd som inte har några biverkningar och inte ändrar dina bevarade data.
Ytterligare resurser
- Globalisering och lokalisering
- Introduktion till Tag Helpers
- Författarens Tag-hjälpare
- Förhindra XSRF-/CSRF-attacker (Cross-Site Request Forgery) i ASP.NET Core
- Skydda kontrollenheten från överpublicering
- ViewModels
- Formulärtagghjälpare
- Hjälp för indatatagg
- Etiketttagghjälpare
- Välj Tag Helper
- Hjälp om verifieringstaggen
ASP.NET Core