Bölüm 6, ASP.NET Core'da denetleyici yöntemleri ve görünümleri
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.
Gönderen Rick Anderson
Film uygulamasına iyi bir başlangıç yaptık, ancak sunu ideal değil, örneğin ReleaseDate iki sözcük olmalıdır.
Models/Movie.cs
Dosyayı açın ve aşağıda gösterilen vurgulanmış satırları ekleyin:
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
sonraki öğreticide açıklanmıştır. Display özniteliği, bir alanın adı için nelerin görüntüleneceğini belirtir (bu örnekte "ReleaseDate" yerine "Yayın Tarihi"). DataType özniteliği verilerin türünü (Tarih) belirtir, bu nedenle alanda depolanan zaman bilgileri görüntülenmez.
Entity Framework Core'un [Column(TypeName = "decimal(18, 2)")]
veritabanındaki para birimine doğru şekilde eşlenebilmesi Price
için veri ek açıklaması gereklidir. Daha fazla bilgi için bkz . Veri Türleri.
Hedef URL'yi Movies
görmek için denetleyiciye göz atın ve fare işaretçisini Düzenle bağlantısının üzerinde tutun.
Düzenle, Ayrıntılar ve Sil bağlantıları, dosyadaki Views/Movies/Index.cshtml
Core MVC Anchor Tag Yardımcısı tarafından oluşturulur.
<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>
Etiket Yardımcıları, Razor dosyalarında HTML öğelerinin oluşturulmasına ve işlenmesine sunucu tarafı kodun katılmasını etkinleştirir. Yukarıdaki koddaAnchorTagHelper
, denetleyici eylem yönteminden ve yol kimliğinden dinamik olarak HTML href
öznitelik değeri oluşturur. Kaynağı Görüntüle'yi sık kullandığınız tarayıcıdan veya geliştirici araçlarını kullanarak oluşturulan işaretlemeyi inceleyebilirsiniz. Oluşturulan HTML'nin bir bölümü aşağıda gösterilmiştir:
<td>
<a href="/Movies/Edit/4"> Edit </a> |
<a href="/Movies/Details/4"> Details </a> |
<a href="/Movies/Delete/4"> Delete </a>
</td>
Dosyada yönlendirme kümesinin biçimini hatırlayınProgram.cs
:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
ASP.NET Core, denetleyicinin eylem yöntemine Movies
4 parametresiyle Id
bir isteğe çevrilirhttps://localhost:5001/Movies/Edit/4
.Edit
(Denetleyici yöntemleri eylem yöntemleri olarak da bilinir.)
Etiket Yardımcıları , ASP.NET Core'daki en popüler yeni özelliklerden biridir. Daha fazla bilgi için bkz . Ek kaynaklar.
Denetleyiciyi Movies
açın ve iki Edit
eylem yöntemini inceleyin. Aşağıdaki kod, filmi getiren ve dosya tarafından Edit.cshtml
Razor oluşturulan düzenleme formunu dolduran yöntemini gösterirHTTP GET Edit
.
// 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);
}
Aşağıdaki kod, gönderilen film değerlerini işleyen yöntemini gösterir HTTP POST Edit
:
// 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);
}
[Bind]
özniteliği, fazla göndermeye karşı korumanın bir yoludur. Özniteliğine [Bind]
yalnızca değiştirmek istediğiniz özellikleri eklemeniz gerekir. Daha fazla bilgi için bkz . Denetleyicinizi fazla göndermeye karşı koruma. ViewModels , fazla göndermeyi önlemek için alternatif bir yaklaşım sağlar.
İkinci Edit
eylem yönteminin önünde özniteliğinin [HttpPost]
olduğuna dikkat edin.
// 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);
}
HttpPost
özniteliği, bu Edit
yöntemin yalnızca istekler için POST
çağrılabileceğini belirtir. özniteliğini [HttpGet]
ilk düzenleme yöntemine uygulayabilirsiniz, ancak varsayılan olduğundan [HttpGet]
bu gerekli değildir.
ValidateAntiForgeryToken
özniteliği, bir isteğin sahteciliğini önlemek için kullanılır ve düzenleme görünümü dosyasında (Views/Movies/Edit.cshtml
) oluşturulan bir sahteciliğe karşı koruma belirteci ile eşleştirilir. Düzenleme görünümü dosyası, Form Etiketi Yardımcısı ile antiforgery belirtecini oluşturur.
<form asp-action="Edit">
Form Etiketi Yardımcısı, Filmler denetleyicisinin yönteminde Edit
oluşturulan sahteciliğe karşı koruma belirteci ile eşleşmesi [ValidateAntiForgeryToken]
gereken gizli bir koruma belirteci oluşturur. Daha fazla bilgi için, bkz. ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme.
HttpGet Edit
yöntemi film ID
parametresini alır, Entity Framework FindAsync
yöntemini kullanarak filmi arar ve seçili filmi Düzenleme görünümüne döndürür. Bir film bulunamazsa NotFound
(HTTP 404) döndürülür.
// 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);
}
yapı iskelesi sistemi Düzenleme görünümünü oluşturduğunda sınıfını inceledi ve sınıfın Movie
her özelliği için ve <input>
öğelerini işlemek <label>
için kod oluşturdu. Aşağıdaki örnekte Visual Studio yapı iskelesi sistemi tarafından oluşturulan Düzenleme görünümü gösterilmektedir:
@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");}
}
Görünüm şablonunun dosyanın en üstünde bir @model MvcMovie.Models.Movie
deyiminin nasıl yer aldığına dikkat edin. @model MvcMovie.Models.Movie
görünümün, görünüm şablonunun modelinin türünde Movie
olmasını beklediğini belirtir.
yapı iskelesi oluşturulmuş kod, HTML işaretlemesini kolaylaştırmak için çeşitli Etiket Yardımcısı yöntemlerini kullanır. Etiket Etiketi Yardımcısı alanın adını ("Title", "ReleaseDate", "Genre" veya "Price") görüntüler. Giriş Etiketi Yardımcısı bir HTML <input>
öğesini işler. Doğrulama Etiketi Yardımcısı, bu özellikle ilişkili tüm doğrulama iletilerini görüntüler.
Uygulamayı çalıştırın ve URL'ye /Movies
gidin. Düzenle bağlantısına tıklayın. Tarayıcıda sayfanın kaynağını görüntüleyin. Öğesi için <form>
oluşturulan HTML aşağıda gösterilmiştir.
<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>
<input>
Öğeler, özniteliği URL'ye gönderi olarak ayarlanmış bir HTML <form>
öğededir action
/Movies/Edit/id
. Düğmeye tıklandığında form verileri sunucuya Save
gönderilir. Kapanış </form>
öğesinden önceki son satır, Form Etiketi Yardımcısı tarafından oluşturulan gizli XSRF belirtecini gösterir.
POST İsteğini İşleme
Aşağıdaki listede eylem yönteminin Edit
sürümü gösterilmektedir[HttpPost]
.
// 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);
}
özniteliği, [ValidateAntiForgeryToken]
Form Etiketi Yardımcısı'ndaki kötü amaçlı belirteç oluşturucu tarafından oluşturulan gizli XSRF belirtecini doğrular
Model bağlama sistemi, gönderilen form değerlerini alır ve parametre olarak movie
geçirilen bir Movie
nesne oluşturur. özelliği, ModelState.IsValid
formda gönderilen verilerin bir Movie
nesneyi değiştirmek (düzenlemek veya güncelleştirmek) için kullanılabileceğini doğrular. Veriler geçerliyse kaydedilir. Güncelleştirilmiş (düzenlenen) film verileri, veritabanı bağlamı yöntemi çağrılarak SaveChangesAsync
veritabanına kaydedilir. Kod, verileri kaydettikten sonra kullanıcıyı Index
, yeni yapılan değişiklikler de dahil olmak üzere film koleksiyonunu görüntüleyen sınıfının eylem yöntemine MoviesController
yönlendirir.
Form sunucuya gönderilmeden önce istemci tarafı doğrulama, alanlardaki doğrulama kurallarını denetler. Doğrulama hataları varsa, bir hata iletisi görüntülenir ve form gönderilmez. JavaScript devre dışı bırakılırsa istemci tarafı doğrulamanız olmaz, ancak sunucu geçerli olmayan postalanan değerleri algılar ve form değerleri hata iletileriyle yeniden görüntülenir. Öğreticinin ilerleyen bölümlerinde Model Doğrulamayı daha ayrıntılı olarak inceleyeceğiz. Görünüm şablonundaki Views/Movies/Edit.cshtml
Doğrulama Etiketi Yardımcısı uygun hata iletilerinin görüntülenmesini sağlar.
Film denetleyicisindeki HttpGet
tüm yöntemler benzer bir deseni izler. Bir film nesnesi (veya olması durumunda Index
nesne listesi) alır ve nesneyi (model) görünüme geçirir. yöntemi, Create
boş bir film nesnesini görünüme Create
geçirir. Verileri oluşturan, düzenleyen, silecek veya başka bir şekilde değiştiren tüm yöntemler, yöntemin [HttpPost]
aşırı yüklemesinde bunu yapar. Bir HTTP GET
yöntemdeki verileri değiştirmek bir güvenlik riskidir. Bir HTTP GET
yöntemdeki verilerin değiştirilmesi, HTTP en iyi yöntemlerini ve GET isteklerinin uygulamanızın durumunu değiştirmemesi gerektiğini belirten mimari REST deseni de ihlal eder. Başka bir deyişle, GET işleminin gerçekleştirilmesi, yan etkisi olmayan ve kalıcı verilerinizi değiştirmeyen güvenli bir işlem olmalıdır.
Ek kaynaklar
- Genelleştirme ve yerelleştirme
- Etiket Yardımcılarına Giriş
- Yazar Etiketi Yardımcıları
- ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme
- Denetleyicinizi fazla göndermeye karşı koruma
- Görünüm Modelleri
- Form Etiketi Yardımcısı
- Giriş Etiketi Yardımcısı
- Etiket Etiketi Yardımcısı
- Seçim Etiketi Yardımcısı
- Doğrulama Etiketi Yardımcısı
Film uygulamasına iyi bir başlangıç yaptık, ancak sunu ideal değil, örneğin ReleaseDate iki sözcük olmalıdır.
Models/Movie.cs
Dosyayı açın ve aşağıda gösterilen vurgulanmış satırları ekleyin:
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
sonraki öğreticide açıklanmıştır. Display özniteliği, bir alanın adı için nelerin görüntüleneceğini belirtir (bu örnekte "ReleaseDate" yerine "Yayın Tarihi"). DataType özniteliği verilerin türünü (Tarih) belirtir, bu nedenle alanda depolanan zaman bilgileri görüntülenmez.
Entity Framework Core'un [Column(TypeName = "decimal(18, 2)")]
veritabanındaki para birimine doğru şekilde eşlenebilmesi Price
için veri ek açıklaması gereklidir. Daha fazla bilgi için bkz . Veri Türleri.
Hedef URL'yi Movies
görmek için denetleyiciye göz atın ve fare işaretçisini Düzenle bağlantısının üzerinde tutun.
Düzenle, Ayrıntılar ve Sil bağlantıları, dosyadaki Views/Movies/Index.cshtml
Core MVC Anchor Tag Yardımcısı tarafından oluşturulur.
<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>
Etiket Yardımcıları, Razor dosyalarında HTML öğelerinin oluşturulmasına ve işlenmesine sunucu tarafı kodun katılmasını etkinleştirir. Yukarıdaki koddaAnchorTagHelper
, denetleyici eylem yönteminden ve yol kimliğinden dinamik olarak HTML href
öznitelik değeri oluşturur. Kaynağı Görüntüle'yi sık kullandığınız tarayıcıdan veya geliştirici araçlarını kullanarak oluşturulan işaretlemeyi inceleyebilirsiniz. Oluşturulan HTML'nin bir bölümü aşağıda gösterilmiştir:
<td>
<a href="/Movies/Edit/4"> Edit </a> |
<a href="/Movies/Details/4"> Details </a> |
<a href="/Movies/Delete/4"> Delete </a>
</td>
Dosyada yönlendirme kümesinin biçimini hatırlayınProgram.cs
:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
ASP.NET Core, denetleyicinin eylem yöntemine Movies
4 parametresiyle Id
bir isteğe çevrilirhttps://localhost:5001/Movies/Edit/4
.Edit
(Denetleyici yöntemleri eylem yöntemleri olarak da bilinir.)
Etiket Yardımcıları , ASP.NET Core'daki en popüler yeni özelliklerden biridir. Daha fazla bilgi için bkz . Ek kaynaklar.
Denetleyiciyi Movies
açın ve iki Edit
eylem yöntemini inceleyin. Aşağıdaki kod, filmi getiren ve dosya tarafından Edit.cshtml
Razor oluşturulan düzenleme formunu dolduran yöntemini gösterirHTTP GET Edit
.
// 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);
}
Aşağıdaki kod, gönderilen film değerlerini işleyen yöntemini gösterir HTTP POST Edit
:
// 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);
}
[Bind]
özniteliği, fazla göndermeye karşı korumanın bir yoludur. Özniteliğine [Bind]
yalnızca değiştirmek istediğiniz özellikleri eklemeniz gerekir. Daha fazla bilgi için bkz . Denetleyicinizi fazla göndermeye karşı koruma. ViewModels , fazla göndermeyi önlemek için alternatif bir yaklaşım sağlar.
İkinci Edit
eylem yönteminin önünde özniteliğinin [HttpPost]
olduğuna dikkat edin.
// 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);
}
HttpPost
özniteliği, bu Edit
yöntemin yalnızca istekler için POST
çağrılabileceğini belirtir. özniteliğini [HttpGet]
ilk düzenleme yöntemine uygulayabilirsiniz, ancak varsayılan olduğundan [HttpGet]
bu gerekli değildir.
ValidateAntiForgeryToken
özniteliği, bir isteğin sahteciliğini önlemek için kullanılır ve düzenleme görünümü dosyasında (Views/Movies/Edit.cshtml
) oluşturulan bir sahteciliğe karşı koruma belirteci ile eşleştirilir. Düzenleme görünümü dosyası, Form Etiketi Yardımcısı ile antiforgery belirtecini oluşturur.
<form asp-action="Edit">
Form Etiketi Yardımcısı, Filmler denetleyicisinin yönteminde Edit
oluşturulan sahteciliğe karşı koruma belirteci ile eşleşmesi [ValidateAntiForgeryToken]
gereken gizli bir koruma belirteci oluşturur. Daha fazla bilgi için, bkz. ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme.
HttpGet Edit
yöntemi film ID
parametresini alır, Entity Framework FindAsync
yöntemini kullanarak filmi arar ve seçili filmi Düzenleme görünümüne döndürür. Bir film bulunamazsa NotFound
(HTTP 404) döndürülür.
// 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);
}
yapı iskelesi sistemi Düzenleme görünümünü oluşturduğunda sınıfını inceledi ve sınıfın Movie
her özelliği için ve <input>
öğelerini işlemek <label>
için kod oluşturdu. Aşağıdaki örnekte Visual Studio yapı iskelesi sistemi tarafından oluşturulan Düzenleme görünümü gösterilmektedir:
@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");}
}
Görünüm şablonunun dosyanın en üstünde bir @model MvcMovie.Models.Movie
deyiminin nasıl yer aldığına dikkat edin. @model MvcMovie.Models.Movie
görünümün, görünüm şablonunun modelinin türünde Movie
olmasını beklediğini belirtir.
yapı iskelesi oluşturulmuş kod, HTML işaretlemesini kolaylaştırmak için çeşitli Etiket Yardımcısı yöntemlerini kullanır. Etiket Etiketi Yardımcısı alanın adını ("Title", "ReleaseDate", "Genre" veya "Price") görüntüler. Giriş Etiketi Yardımcısı bir HTML <input>
öğesini işler. Doğrulama Etiketi Yardımcısı, bu özellikle ilişkili tüm doğrulama iletilerini görüntüler.
Uygulamayı çalıştırın ve URL'ye /Movies
gidin. Düzenle bağlantısına tıklayın. Tarayıcıda sayfanın kaynağını görüntüleyin. Öğesi için <form>
oluşturulan HTML aşağıda gösterilmiştir.
<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>
<input>
Öğeler, özniteliği URL'ye gönderi olarak ayarlanmış bir HTML <form>
öğededir action
/Movies/Edit/id
. Düğmeye tıklandığında form verileri sunucuya Save
gönderilir. Kapanış </form>
öğesinden önceki son satır, Form Etiketi Yardımcısı tarafından oluşturulan gizli XSRF belirtecini gösterir.
POST İsteğini İşleme
Aşağıdaki listede eylem yönteminin Edit
sürümü gösterilmektedir[HttpPost]
.
// 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);
}
özniteliği, [ValidateAntiForgeryToken]
Form Etiketi Yardımcısı'ndaki kötü amaçlı belirteç oluşturucu tarafından oluşturulan gizli XSRF belirtecini doğrular
Model bağlama sistemi, gönderilen form değerlerini alır ve parametre olarak movie
geçirilen bir Movie
nesne oluşturur. özelliği, ModelState.IsValid
formda gönderilen verilerin bir Movie
nesneyi değiştirmek (düzenlemek veya güncelleştirmek) için kullanılabileceğini doğrular. Veriler geçerliyse kaydedilir. Güncelleştirilmiş (düzenlenen) film verileri, veritabanı bağlamı yöntemi çağrılarak SaveChangesAsync
veritabanına kaydedilir. Kod, verileri kaydettikten sonra kullanıcıyı Index
, yeni yapılan değişiklikler de dahil olmak üzere film koleksiyonunu görüntüleyen sınıfının eylem yöntemine MoviesController
yönlendirir.
Form sunucuya gönderilmeden önce istemci tarafı doğrulama, alanlardaki doğrulama kurallarını denetler. Doğrulama hataları varsa, bir hata iletisi görüntülenir ve form gönderilmez. JavaScript devre dışı bırakılırsa istemci tarafı doğrulamanız olmaz, ancak sunucu geçerli olmayan postalanan değerleri algılar ve form değerleri hata iletileriyle yeniden görüntülenir. Öğreticinin ilerleyen bölümlerinde Model Doğrulamayı daha ayrıntılı olarak inceleyeceğiz. Görünüm şablonundaki Views/Movies/Edit.cshtml
Doğrulama Etiketi Yardımcısı uygun hata iletilerinin görüntülenmesini sağlar.
Film denetleyicisindeki HttpGet
tüm yöntemler benzer bir deseni izler. Bir film nesnesi (veya olması durumunda Index
nesne listesi) alır ve nesneyi (model) görünüme geçirir. yöntemi, Create
boş bir film nesnesini görünüme Create
geçirir. Verileri oluşturan, düzenleyen, silecek veya başka bir şekilde değiştiren tüm yöntemler, yöntemin [HttpPost]
aşırı yüklemesinde bunu yapar. Bir HTTP GET
yöntemdeki verileri değiştirmek bir güvenlik riskidir. Bir HTTP GET
yöntemdeki verilerin değiştirilmesi, HTTP en iyi yöntemlerini ve GET isteklerinin uygulamanızın durumunu değiştirmemesi gerektiğini belirten mimari REST deseni de ihlal eder. Başka bir deyişle, GET işleminin gerçekleştirilmesi, yan etkisi olmayan ve kalıcı verilerinizi değiştirmeyen güvenli bir işlem olmalıdır.
Ek kaynaklar
- Genelleştirme ve yerelleştirme
- Etiket Yardımcılarına Giriş
- Yazar Etiketi Yardımcıları
- ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme
- Denetleyicinizi fazla göndermeye karşı koruma
- Görünüm Modelleri
- Form Etiketi Yardımcısı
- Giriş Etiketi Yardımcısı
- Etiket Etiketi Yardımcısı
- Seçim Etiketi Yardımcısı
- Doğrulama Etiketi Yardımcısı
Film uygulamasına iyi bir başlangıç yaptık, ancak sunu ideal değil, örneğin ReleaseDate iki sözcük olmalıdır.
Models/Movie.cs
Dosyayı açın ve aşağıda gösterilen vurgulanmış satırları ekleyin:
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
sonraki öğreticide açıklanmıştır. Display özniteliği, bir alanın adı için nelerin görüntüleneceğini belirtir (bu örnekte "ReleaseDate" yerine "Yayın Tarihi"). DataType özniteliği verilerin türünü (Tarih) belirtir, bu nedenle alanda depolanan zaman bilgileri görüntülenmez.
Entity Framework Core'un [Column(TypeName = "decimal(18, 2)")]
veritabanındaki para birimine doğru şekilde eşlenebilmesi Price
için veri ek açıklaması gereklidir. Daha fazla bilgi için bkz . Veri Türleri.
Hedef URL'yi Movies
görmek için denetleyiciye göz atın ve fare işaretçisini Düzenle bağlantısının üzerinde tutun.
Düzenle, Ayrıntılar ve Sil bağlantıları, dosyadaki Views/Movies/Index.cshtml
Core MVC Anchor Tag Yardımcısı tarafından oluşturulur.
<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>
Etiket Yardımcıları, Razor dosyalarında HTML öğelerinin oluşturulmasına ve işlenmesine sunucu tarafı kodun katılmasını etkinleştirir. Yukarıdaki koddaAnchorTagHelper
, denetleyici eylem yönteminden ve yol kimliğinden dinamik olarak HTML href
öznitelik değeri oluşturur. Kaynağı Görüntüle'yi sık kullandığınız tarayıcıdan veya geliştirici araçlarını kullanarak oluşturulan işaretlemeyi inceleyebilirsiniz. Oluşturulan HTML'nin bir bölümü aşağıda gösterilmiştir:
<td>
<a href="/Movies/Edit/4"> Edit </a> |
<a href="/Movies/Details/4"> Details </a> |
<a href="/Movies/Delete/4"> Delete </a>
</td>
Dosyada yönlendirme kümesinin biçimini hatırlayınProgram.cs
:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
ASP.NET Core, denetleyicinin eylem yöntemine Movies
4 parametresiyle Id
bir isteğe çevrilirhttps://localhost:5001/Movies/Edit/4
.Edit
(Denetleyici yöntemleri eylem yöntemleri olarak da bilinir.)
Etiket Yardımcıları , ASP.NET Core'daki en popüler yeni özelliklerden biridir. Daha fazla bilgi için bkz . Ek kaynaklar.
Denetleyiciyi Movies
açın ve iki Edit
eylem yöntemini inceleyin. Aşağıdaki kod, filmi getiren ve dosya tarafından Edit.cshtml
Razor oluşturulan düzenleme formunu dolduran yöntemini gösterirHTTP GET Edit
.
// 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);
}
Aşağıdaki kod, gönderilen film değerlerini işleyen yöntemini gösterir HTTP POST Edit
:
// 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);
}
[Bind]
özniteliği, fazla göndermeye karşı korumanın bir yoludur. Özniteliğine [Bind]
yalnızca değiştirmek istediğiniz özellikleri eklemeniz gerekir. Daha fazla bilgi için bkz . Denetleyicinizi fazla göndermeye karşı koruma. ViewModels , fazla göndermeyi önlemek için alternatif bir yaklaşım sağlar.
İkinci Edit
eylem yönteminin önünde özniteliğinin [HttpPost]
olduğuna dikkat edin.
// 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);
}
HttpPost
özniteliği, bu Edit
yöntemin yalnızca istekler için POST
çağrılabileceğini belirtir. özniteliğini [HttpGet]
ilk düzenleme yöntemine uygulayabilirsiniz, ancak varsayılan olduğundan [HttpGet]
bu gerekli değildir.
ValidateAntiForgeryToken
özniteliği, bir isteğin sahteciliğini önlemek için kullanılır ve düzenleme görünümü dosyasında (Views/Movies/Edit.cshtml
) oluşturulan bir sahteciliğe karşı koruma belirteci ile eşleştirilir. Düzenleme görünümü dosyası, Form Etiketi Yardımcısı ile antiforgery belirtecini oluşturur.
<form asp-action="Edit">
Form Etiketi Yardımcısı, Filmler denetleyicisinin yönteminde Edit
oluşturulan sahteciliğe karşı koruma belirteci ile eşleşmesi [ValidateAntiForgeryToken]
gereken gizli bir koruma belirteci oluşturur. Daha fazla bilgi için, bkz. ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme.
HttpGet Edit
yöntemi film ID
parametresini alır, Entity Framework FindAsync
yöntemini kullanarak filmi arar ve seçili filmi Düzenleme görünümüne döndürür. Bir film bulunamazsa NotFound
(HTTP 404) döndürülür.
// 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);
}
yapı iskelesi sistemi Düzenleme görünümünü oluşturduğunda sınıfını inceledi ve sınıfın Movie
her özelliği için ve <input>
öğelerini işlemek <label>
için kod oluşturdu. Aşağıdaki örnekte Visual Studio yapı iskelesi sistemi tarafından oluşturulan Düzenleme görünümü gösterilmektedir:
@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");}
}
Görünüm şablonunun dosyanın en üstünde bir @model MvcMovie.Models.Movie
deyiminin nasıl yer aldığına dikkat edin. @model MvcMovie.Models.Movie
görünümün, görünüm şablonunun modelinin türünde Movie
olmasını beklediğini belirtir.
yapı iskelesi oluşturulmuş kod, HTML işaretlemesini kolaylaştırmak için çeşitli Etiket Yardımcısı yöntemlerini kullanır. Etiket Etiketi Yardımcısı alanın adını ("Title", "ReleaseDate", "Genre" veya "Price") görüntüler. Giriş Etiketi Yardımcısı bir HTML <input>
öğesini işler. Doğrulama Etiketi Yardımcısı, bu özellikle ilişkili tüm doğrulama iletilerini görüntüler.
Uygulamayı çalıştırın ve URL'ye /Movies
gidin. Düzenle bağlantısına tıklayın. Tarayıcıda sayfanın kaynağını görüntüleyin. Öğesi için <form>
oluşturulan HTML aşağıda gösterilmiştir.
<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>
<input>
Öğeler, özniteliği URL'ye gönderi olarak ayarlanmış bir HTML <form>
öğededir action
/Movies/Edit/id
. Düğmeye tıklandığında form verileri sunucuya Save
gönderilir. Kapanış </form>
öğesinden önceki son satır, Form Etiketi Yardımcısı tarafından oluşturulan gizli XSRF belirtecini gösterir.
POST İsteğini İşleme
Aşağıdaki listede eylem yönteminin Edit
sürümü gösterilmektedir[HttpPost]
.
// 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);
}
özniteliği, [ValidateAntiForgeryToken]
Form Etiketi Yardımcısı'ndaki kötü amaçlı belirteç oluşturucu tarafından oluşturulan gizli XSRF belirtecini doğrular
Model bağlama sistemi, gönderilen form değerlerini alır ve parametre olarak movie
geçirilen bir Movie
nesne oluşturur. özelliği, ModelState.IsValid
formda gönderilen verilerin bir Movie
nesneyi değiştirmek (düzenlemek veya güncelleştirmek) için kullanılabileceğini doğrular. Veriler geçerliyse kaydedilir. Güncelleştirilmiş (düzenlenen) film verileri, veritabanı bağlamı yöntemi çağrılarak SaveChangesAsync
veritabanına kaydedilir. Kod, verileri kaydettikten sonra kullanıcıyı Index
, yeni yapılan değişiklikler de dahil olmak üzere film koleksiyonunu görüntüleyen sınıfının eylem yöntemine MoviesController
yönlendirir.
Form sunucuya gönderilmeden önce istemci tarafı doğrulama, alanlardaki doğrulama kurallarını denetler. Doğrulama hataları varsa, bir hata iletisi görüntülenir ve form gönderilmez. JavaScript devre dışı bırakılırsa istemci tarafı doğrulamanız olmaz, ancak sunucu geçerli olmayan postalanan değerleri algılar ve form değerleri hata iletileriyle yeniden görüntülenir. Öğreticinin ilerleyen bölümlerinde Model Doğrulamayı daha ayrıntılı olarak inceleyeceğiz. Görünüm şablonundaki Views/Movies/Edit.cshtml
Doğrulama Etiketi Yardımcısı uygun hata iletilerinin görüntülenmesini sağlar.
Film denetleyicisindeki HttpGet
tüm yöntemler benzer bir deseni izler. Bir film nesnesi (veya olması durumunda Index
nesne listesi) alır ve nesneyi (model) görünüme geçirir. yöntemi, Create
boş bir film nesnesini görünüme Create
geçirir. Verileri oluşturan, düzenleyen, silecek veya başka bir şekilde değiştiren tüm yöntemler, yöntemin [HttpPost]
aşırı yüklemesinde bunu yapar. Bir HTTP GET
yöntemdeki verileri değiştirmek bir güvenlik riskidir. Bir HTTP GET
yöntemdeki verilerin değiştirilmesi, HTTP en iyi yöntemlerini ve GET isteklerinin uygulamanızın durumunu değiştirmemesi gerektiğini belirten mimari REST deseni de ihlal eder. Başka bir deyişle, GET işleminin gerçekleştirilmesi, yan etkisi olmayan ve kalıcı verilerinizi değiştirmeyen güvenli bir işlem olmalıdır.
Ek kaynaklar
- Genelleştirme ve yerelleştirme
- Etiket Yardımcılarına Giriş
- Yazar Etiketi Yardımcıları
- ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme
- Denetleyicinizi fazla göndermeye karşı koruma
- Görünüm Modelleri
- Form Etiketi Yardımcısı
- Giriş Etiketi Yardımcısı
- Etiket Etiketi Yardımcısı
- Seçim Etiketi Yardımcısı
- Doğrulama Etiketi Yardımcısı
Film uygulamasına iyi bir başlangıç yaptık, ancak sunu ideal değil, örneğin ReleaseDate iki sözcük olmalıdır.
Models/Movie.cs
Dosyayı açın ve aşağıda gösterilen vurgulanmış satırları ekleyin:
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
sonraki öğreticide açıklanmıştır. Display özniteliği, bir alanın adı için nelerin görüntüleneceğini belirtir (bu örnekte "ReleaseDate" yerine "Yayın Tarihi"). DataType özniteliği verilerin türünü (Tarih) belirtir, bu nedenle alanda depolanan zaman bilgileri görüntülenmez.
Entity Framework Core'un [Column(TypeName = "decimal(18, 2)")]
veritabanındaki para birimine doğru şekilde eşlenebilmesi Price
için veri ek açıklaması gereklidir. Daha fazla bilgi için bkz . Veri Türleri.
Hedef URL'yi Movies
görmek için denetleyiciye göz atın ve fare işaretçisini Düzenle bağlantısının üzerinde tutun.
Düzenle, Ayrıntılar ve Sil bağlantıları, dosyadaki Views/Movies/Index.cshtml
Core MVC Anchor Tag Yardımcısı tarafından oluşturulur.
<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>
Etiket Yardımcıları, Razor dosyalarında HTML öğelerinin oluşturulmasına ve işlenmesine sunucu tarafı kodun katılmasını etkinleştirir. Yukarıdaki koddaAnchorTagHelper
, denetleyici eylem yönteminden ve yol kimliğinden dinamik olarak HTML href
öznitelik değeri oluşturur. Kaynağı Görüntüle'yi sık kullandığınız tarayıcıdan veya geliştirici araçlarını kullanarak oluşturulan işaretlemeyi inceleyebilirsiniz. Oluşturulan HTML'nin bir bölümü aşağıda gösterilmiştir:
<td>
<a href="/Movies/Edit/4"> Edit </a> |
<a href="/Movies/Details/4"> Details </a> |
<a href="/Movies/Delete/4"> Delete </a>
</td>
Dosyada yönlendirme kümesinin biçimini hatırlayınProgram.cs
:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
ASP.NET Core, denetleyicinin eylem yöntemine Movies
4 parametresiyle Id
bir isteğe çevrilirhttps://localhost:5001/Movies/Edit/4
.Edit
(Denetleyici yöntemleri eylem yöntemleri olarak da bilinir.)
Etiket Yardımcıları , ASP.NET Core'daki popüler bir özelliktir. Bunlar hakkında daha fazla bilgi için bkz . Ek kaynaklar.
Denetleyiciyi Movies
açın ve iki Edit
eylem yöntemini inceleyin. Aşağıdaki kod, filmi getiren ve dosya tarafından Edit.cshtml
Razor oluşturulan düzenleme formunu dolduran yöntemini gösterirHTTP GET Edit
.
// 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);
}
Aşağıdaki kod, gönderilen film değerlerini işleyen yöntemini gösterir HTTP POST Edit
:
// 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);
}
[Bind]
özniteliği, fazla göndermeye karşı korumanın bir yoludur. Özniteliğine [Bind]
yalnızca değiştirmek istediğiniz özellikleri eklemeniz gerekir. Daha fazla bilgi için bkz . Denetleyicinizi fazla göndermeye karşı koruma. ViewModels , fazla göndermeyi önlemek için alternatif bir yaklaşım sağlar.
İkinci Edit
eylem yönteminin önünde özniteliğinin [HttpPost]
olduğuna dikkat edin.
// 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);
}
HttpPost
özniteliği, bu Edit
yöntemin yalnızca istekler için POST
çağrılabileceğini belirtir. özniteliğini [HttpGet]
ilk düzenleme yöntemine uygulayabilirsiniz, ancak varsayılan olduğundan [HttpGet]
bu gerekli değildir.
ValidateAntiForgeryToken
özniteliği, bir isteğin sahteciliğini önlemek için kullanılır ve düzenleme görünümü dosyasında (Views/Movies/Edit.cshtml
) oluşturulan bir sahteciliğe karşı koruma belirteci ile eşleştirilir. Düzenleme görünümü dosyası, Form Etiketi Yardımcısı ile antiforgery belirtecini oluşturur.
<form asp-action="Edit">
Form Etiketi Yardımcısı, Filmler denetleyicisinin yönteminde Edit
oluşturulan sahteciliğe karşı koruma belirteci ile eşleşmesi [ValidateAntiForgeryToken]
gereken gizli bir koruma belirteci oluşturur. Daha fazla bilgi için, bkz. ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme.
HttpGet Edit
yöntemi film ID
parametresini alır, Entity Framework FindAsync
yöntemini kullanarak filmi arar ve seçili filmi Düzenleme görünümüne döndürür. Bir film bulunamazsa NotFound
(HTTP 404) döndürülür.
// 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);
}
yapı iskelesi sistemi Düzenleme görünümünü oluşturduğunda sınıfını inceledi ve sınıfın Movie
her özelliği için ve <input>
öğelerini işlemek <label>
için kod oluşturdu. Aşağıdaki örnekte Visual Studio yapı iskelesi sistemi tarafından oluşturulan Düzenleme görünümü gösterilmektedir:
@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");}
}
Görünüm şablonunun dosyanın en üstünde bir @model MvcMovie.Models.Movie
deyiminin nasıl yer aldığına dikkat edin. @model MvcMovie.Models.Movie
görünümün, görünüm şablonunun modelinin türünde Movie
olmasını beklediğini belirtir.
yapı iskelesi oluşturulmuş kod, HTML işaretlemesini kolaylaştırmak için çeşitli Etiket Yardımcısı yöntemlerini kullanır. Etiket Etiketi Yardımcısı alanın adını ("Title", "ReleaseDate", "Genre" veya "Price") görüntüler. Giriş Etiketi Yardımcısı bir HTML <input>
öğesini işler. Doğrulama Etiketi Yardımcısı, bu özellikle ilişkili tüm doğrulama iletilerini görüntüler.
Uygulamayı çalıştırın ve URL'ye /Movies
gidin. Düzenle bağlantısına tıklayın. Tarayıcıda sayfanın kaynağını görüntüleyin. Öğesi için <form>
oluşturulan HTML aşağıda gösterilmiştir.
<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>
<input>
Öğeler, özniteliği URL'ye gönderi olarak ayarlanmış bir HTML <form>
öğededir action
/Movies/Edit/id
. Düğmeye tıklandığında form verileri sunucuya Save
gönderilir. Kapanış </form>
öğesinden önceki son satır, Form Etiketi Yardımcısı tarafından oluşturulan gizli XSRF belirtecini gösterir.
POST İsteğini İşleme
Aşağıdaki listede eylem yönteminin Edit
sürümü gösterilmektedir[HttpPost]
.
// 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);
}
özniteliği, [ValidateAntiForgeryToken]
Form Etiketi Yardımcısı'ndaki kötü amaçlı belirteç oluşturucu tarafından oluşturulan gizli XSRF belirtecini doğrular
Model bağlama sistemi, gönderilen form değerlerini alır ve parametre olarak movie
geçirilen bir Movie
nesne oluşturur. özelliği, ModelState.IsValid
formda gönderilen verilerin bir Movie
nesneyi değiştirmek (düzenlemek veya güncelleştirmek) için kullanılabileceğini doğrular. Veriler geçerliyse kaydedilir. Güncelleştirilmiş (düzenlenen) film verileri, veritabanı bağlamı yöntemi çağrılarak SaveChangesAsync
veritabanına kaydedilir. Kod, verileri kaydettikten sonra kullanıcıyı Index
, yeni yapılan değişiklikler de dahil olmak üzere film koleksiyonunu görüntüleyen sınıfının eylem yöntemine MoviesController
yönlendirir.
Form sunucuya gönderilmeden önce istemci tarafı doğrulama, alanlardaki doğrulama kurallarını denetler. Doğrulama hataları varsa, bir hata iletisi görüntülenir ve form gönderilmez. JavaScript devre dışı bırakılırsa istemci tarafı doğrulamanız olmaz, ancak sunucu geçerli olmayan postalanan değerleri algılar ve form değerleri hata iletileriyle yeniden görüntülenir. Öğreticinin ilerleyen bölümlerinde Model Doğrulamayı daha ayrıntılı olarak inceleyeceğiz. Görünüm şablonundaki Views/Movies/Edit.cshtml
Doğrulama Etiketi Yardımcısı uygun hata iletilerinin görüntülenmesini sağlar.
Film denetleyicisindeki HttpGet
tüm yöntemler benzer bir deseni izler. Bir film nesnesi (veya olması durumunda Index
nesne listesi) alır ve nesneyi (model) görünüme geçirir. yöntemi, Create
boş bir film nesnesini görünüme Create
geçirir. Verileri oluşturan, düzenleyen, silecek veya başka bir şekilde değiştiren tüm yöntemler, yöntemin [HttpPost]
aşırı yüklemesinde bunu yapar. Bir HTTP GET
yöntemdeki verileri değiştirmek bir güvenlik riskidir. Bir HTTP GET
yöntemdeki verilerin değiştirilmesi, HTTP en iyi yöntemlerini ve GET isteklerinin uygulamanızın durumunu değiştirmemesi gerektiğini belirten mimari REST deseni de ihlal eder. Başka bir deyişle, GET işleminin gerçekleştirilmesi, yan etkisi olmayan ve kalıcı verilerinizi değiştirmeyen güvenli bir işlem olmalıdır.
Ek kaynaklar
- Genelleştirme ve yerelleştirme
- Etiket Yardımcılarına Giriş
- Yazar Etiketi Yardımcıları
- ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme
- Denetleyicinizi fazla göndermeye karşı koruma
- Görünüm Modelleri
- Form Etiketi Yardımcısı
- Giriş Etiketi Yardımcısı
- Etiket Etiketi Yardımcısı
- Seçim Etiketi Yardımcısı
- Doğrulama Etiketi Yardımcısı
Film uygulamasına iyi bir başlangıç yaptık, ancak sunu ideal değil, örneğin ReleaseDate iki sözcük olmalıdır.
Models/Movie.cs
Dosyayı açın ve aşağıda gösterilen vurgulanmış satırları ekleyin:
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; }
}
}
Sonraki öğreticide DataAnnotations'ı ele alacağız. Display özniteliği, bir alanın adı için nelerin görüntüleneceğini belirtir (bu örnekte "ReleaseDate" yerine "Yayın Tarihi"). DataType özniteliği verilerin türünü (Tarih) belirtir, bu nedenle alanda depolanan zaman bilgileri görüntülenmez.
Entity Framework Core'un [Column(TypeName = "decimal(18, 2)")]
veritabanındaki para birimine doğru şekilde eşlenebilmesi Price
için veri ek açıklaması gereklidir. Daha fazla bilgi için bkz . Veri Türleri.
Hedef URL'yi Movies
görmek için denetleyiciye göz atın ve fare işaretçisini Düzenle bağlantısının üzerinde tutun.
Düzenle, Ayrıntılar ve Sil bağlantıları, dosyadaki Views/Movies/Index.cshtml
Core MVC Anchor Tag Yardımcısı tarafından oluşturulur.
<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>
Etiket Yardımcıları, Razor dosyalarında HTML öğelerinin oluşturulmasına ve işlenmesine sunucu tarafı kodun katılmasını etkinleştirir. Yukarıdaki koddaAnchorTagHelper
, denetleyici eylem yönteminden ve yol kimliğinden dinamik olarak HTML href
öznitelik değeri oluşturur. Kaynağı Görüntüle'yi sık kullandığınız tarayıcıdan veya geliştirici araçlarını kullanarak oluşturulan işaretlemeyi inceleyebilirsiniz. Oluşturulan HTML'nin bir bölümü aşağıda gösterilmiştir:
<td>
<a href="/Movies/Edit/4"> Edit </a> |
<a href="/Movies/Details/4"> Details </a> |
<a href="/Movies/Delete/4"> Delete </a>
</td>
Dosyada yönlendirme kümesinin biçimini hatırlayınStartup.cs
:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
ASP.NET Core, denetleyicinin eylem yöntemine Movies
4 parametresiyle Id
bir isteğe çevrilirhttps://localhost:5001/Movies/Edit/4
.Edit
(Denetleyici yöntemleri eylem yöntemleri olarak da bilinir.)
Etiket Yardımcıları hakkında daha fazla bilgi için bkz. Ek kaynaklar.
Denetleyiciyi Movies
açın ve iki Edit
eylem yöntemini inceleyin. Aşağıdaki kod, filmi getiren ve dosya tarafından Edit.cshtml
Razor oluşturulan düzenleme formunu dolduran yöntemini gösterirHTTP GET Edit
.
// 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);
}
Aşağıdaki kod, gönderilen film değerlerini işleyen yöntemini gösterir HTTP POST Edit
:
// 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);
}
[Bind]
özniteliği, fazla göndermeye karşı korumanın bir yoludur. Özniteliğine [Bind]
yalnızca değiştirmek istediğiniz özellikleri eklemeniz gerekir. Daha fazla bilgi için bkz . Denetleyicinizi fazla göndermeye karşı koruma. ViewModels , fazla göndermeyi önlemek için alternatif bir yaklaşım sağlar.
İkinci Edit
eylem yönteminin önünde özniteliğinin [HttpPost]
olduğuna dikkat edin.
[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);
}
HttpPost
özniteliği, bu Edit
yöntemin yalnızca istekler için POST
çağrılabileceğini belirtir. özniteliğini [HttpGet]
ilk düzenleme yöntemine uygulayabilirsiniz, ancak varsayılan olduğundan [HttpGet]
bu gerekli değildir.
ValidateAntiForgeryToken
özniteliği, bir isteğin sahteciliğini önlemek için kullanılır ve düzenleme görünümü dosyasında (Views/Movies/Edit.cshtml
) oluşturulan bir sahteciliğe karşı koruma belirteci ile eşleştirilir. Düzenleme görünümü dosyası, Form Etiketi Yardımcısı ile antiforgery belirtecini oluşturur.
<form asp-action="Edit">
Form Etiketi Yardımcısı, Filmler denetleyicisinin yönteminde Edit
oluşturulan sahteciliğe karşı koruma belirteci ile eşleşmesi [ValidateAntiForgeryToken]
gereken gizli bir koruma belirteci oluşturur. Daha fazla bilgi için, bkz. ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme.
HttpGet Edit
yöntemi film ID
parametresini alır, Entity Framework FindAsync
yöntemini kullanarak filmi arar ve seçili filmi Düzenleme görünümüne döndürür. Bir film bulunamazsa NotFound
(HTTP 404) döndürülür.
// 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);
}
yapı iskelesi sistemi Düzenleme görünümünü oluşturduğunda sınıfını inceledi ve sınıfın Movie
her özelliği için ve <input>
öğelerini işlemek <label>
için kod oluşturdu. Aşağıdaki örnekte Visual Studio yapı iskelesi sistemi tarafından oluşturulan Düzenleme görünümü gösterilmektedir:
@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");}
}
Görünüm şablonunun dosyanın en üstünde bir @model MvcMovie.Models.Movie
deyiminin nasıl yer aldığına dikkat edin. @model MvcMovie.Models.Movie
görünümün, görünüm şablonunun modelinin türünde Movie
olmasını beklediğini belirtir.
yapı iskelesi oluşturulmuş kod, HTML işaretlemesini kolaylaştırmak için çeşitli Etiket Yardımcısı yöntemlerini kullanır. Etiket Etiketi Yardımcısı alanın adını ("Title", "ReleaseDate", "Genre" veya "Price") görüntüler. Giriş Etiketi Yardımcısı bir HTML <input>
öğesini işler. Doğrulama Etiketi Yardımcısı, bu özellikle ilişkili tüm doğrulama iletilerini görüntüler.
Uygulamayı çalıştırın ve URL'ye /Movies
gidin. Düzenle bağlantısına tıklayın. Tarayıcıda sayfanın kaynağını görüntüleyin. Öğesi için <form>
oluşturulan HTML aşağıda gösterilmiştir.
<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>
<input>
Öğeler, özniteliği URL'ye gönderi olarak ayarlanmış bir HTML <form>
öğededir action
/Movies/Edit/id
. Düğmeye tıklandığında form verileri sunucuya Save
gönderilir. Kapanış </form>
öğesinden önceki son satır, Form Etiketi Yardımcısı tarafından oluşturulan gizli XSRF belirtecini gösterir.
POST İsteğini İşleme
Aşağıdaki listede eylem yönteminin Edit
sürümü gösterilmektedir[HttpPost]
.
[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);
}
özniteliği, [ValidateAntiForgeryToken]
Form Etiketi Yardımcısı'ndaki kötü amaçlı belirteç oluşturucu tarafından oluşturulan gizli XSRF belirtecini doğrular
Model bağlama sistemi, gönderilen form değerlerini alır ve parametre olarak movie
geçirilen bir Movie
nesne oluşturur. özelliği, ModelState.IsValid
formda gönderilen verilerin bir Movie
nesneyi değiştirmek (düzenlemek veya güncelleştirmek) için kullanılabileceğini doğrular. Veriler geçerliyse kaydedilir. Güncelleştirilmiş (düzenlenen) film verileri, veritabanı bağlamı yöntemi çağrılarak SaveChangesAsync
veritabanına kaydedilir. Kod, verileri kaydettikten sonra kullanıcıyı Index
, yeni yapılan değişiklikler de dahil olmak üzere film koleksiyonunu görüntüleyen sınıfının eylem yöntemine MoviesController
yönlendirir.
Form sunucuya gönderilmeden önce istemci tarafı doğrulama, alanlardaki doğrulama kurallarını denetler. Doğrulama hataları varsa, bir hata iletisi görüntülenir ve form gönderilmez. JavaScript devre dışı bırakılırsa istemci tarafı doğrulamanız olmaz, ancak sunucu geçerli olmayan postalanan değerleri algılar ve form değerleri hata iletileriyle yeniden görüntülenir. Öğreticinin ilerleyen bölümlerinde Model Doğrulamayı daha ayrıntılı olarak inceleyeceğiz. Görünüm şablonundaki Views/Movies/Edit.cshtml
Doğrulama Etiketi Yardımcısı uygun hata iletilerinin görüntülenmesini sağlar.
Film denetleyicisindeki HttpGet
tüm yöntemler benzer bir deseni izler. Bir film nesnesi (veya olması durumunda Index
nesne listesi) alır ve nesneyi (model) görünüme geçirir. yöntemi, Create
boş bir film nesnesini görünüme Create
geçirir. Verileri oluşturan, düzenleyen, silecek veya başka bir şekilde değiştiren tüm yöntemler, yöntemin [HttpPost]
aşırı yüklemesinde bunu yapar. Bir HTTP GET
yöntemdeki verileri değiştirmek bir güvenlik riskidir. Bir HTTP GET
yöntemdeki verilerin değiştirilmesi, HTTP en iyi yöntemlerini ve GET isteklerinin uygulamanızın durumunu değiştirmemesi gerektiğini belirten mimari REST deseni de ihlal eder. Başka bir deyişle, GET işleminin gerçekleştirilmesi, yan etkisi olmayan ve kalıcı verilerinizi değiştirmeyen güvenli bir işlem olmalıdır.
Ek kaynaklar
- Genelleştirme ve yerelleştirme
- Etiket Yardımcılarına Giriş
- Yazar Etiketi Yardımcıları
- ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme
- Denetleyicinizi fazla göndermeye karşı koruma
- Görünüm Modelleri
- Form Etiketi Yardımcısı
- Giriş Etiketi Yardımcısı
- Etiket Etiketi Yardımcısı
- Seçim Etiketi Yardımcısı
- Doğrulama Etiketi Yardımcısı
ASP.NET Core