Share via


Bölüm 6, ASP.NET Core'da denetleyici yöntemleri ve görünümleri

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

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.

Dizin görünümü: Yayın Tarihi bir sözcük (boşluk yok) ve her film yayın tarihi saat olarak 12:00'yi gösterir

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 bağlantısının üzerinde fareyle tarayıcı penceresi ve bağlantı Url'si https://localhost:5001/Movies/Edit/5 gösterilir

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.cshtmlRazor 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 sahteciliğe karşı koruma belirtecini oluşturur.

<form asp-action="Edit">

Form Etiketi Yardımcısı, Filmler denetleyicisinin yönteminde Edit oluşturulan sahtecilik önleme belirteciyle [ValidateAntiForgeryToken] eşleşmesi gereken gizli bir sahtecilik önleme 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 Movieolması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ı'nda sahte 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.

Düzenleme görünümü: Abc'nin yanlış Fiyat değeri için özel durum, Price alanının bir sayı olması gerektiğini belirtir. xyz durumlarının hatalı Yayın Tarihi değeri için özel durum Lütfen geçerli bir tarih girin.

Film denetleyicisindeki HttpGet tüm yöntemler benzer bir deseni izler. Bir film nesnesi (veya olması durumunda Indexnesne 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

Film uygulamasına iyi bir başlangıç yaptık, ancak sunu ideal değil, örneğin ReleaseDate iki sözcük olmalıdır.

Dizin görünümü: Yayın Tarihi bir sözcük (boşluk yok) ve her film yayın tarihi saat olarak 12:00'yi gösterir

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 bağlantısının üzerinde fareyle tarayıcı penceresi ve bağlantı Url'si https://localhost:5001/Movies/Edit/5 gösterilir

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.cshtmlRazor 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 sahteciliğe karşı koruma belirtecini oluşturur.

<form asp-action="Edit">

Form Etiketi Yardımcısı, Filmler denetleyicisinin yönteminde Edit oluşturulan sahtecilik önleme belirteciyle [ValidateAntiForgeryToken] eşleşmesi gereken gizli bir sahtecilik önleme 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 Movieolması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ı'nda sahte 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.

Düzenleme görünümü: Abc'nin yanlış Fiyat değeri için özel durum, Price alanının bir sayı olması gerektiğini belirtir. xyz durumlarının hatalı Yayın Tarihi değeri için özel durum Lütfen geçerli bir tarih girin.

Film denetleyicisindeki HttpGet tüm yöntemler benzer bir deseni izler. Bir film nesnesi (veya olması durumunda Indexnesne 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

Film uygulamasına iyi bir başlangıç yaptık, ancak sunu ideal değil, örneğin ReleaseDate iki sözcük olmalıdır.

Dizin görünümü: Yayın Tarihi bir sözcük (boşluk yok) ve her film yayın tarihi saat olarak 12:00'yi gösterir

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 bağlantısının üzerinde fareyle tarayıcı penceresi ve bağlantı Url'si https://localhost:5001/Movies/Edit/5 gösterilir

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.cshtmlRazor 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 sahteciliğe karşı koruma belirtecini oluşturur.

<form asp-action="Edit">

Form Etiketi Yardımcısı, Filmler denetleyicisinin yönteminde Edit oluşturulan sahtecilik önleme belirteciyle [ValidateAntiForgeryToken] eşleşmesi gereken gizli bir sahtecilik önleme 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 Movieolması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ı'nda sahte 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.

Düzenleme görünümü: Abc'nin yanlış Fiyat değeri için özel durum, Price alanının bir sayı olması gerektiğini belirtir. xyz durumlarının hatalı Yayın Tarihi değeri için özel durum Lütfen geçerli bir tarih girin.

Film denetleyicisindeki HttpGet tüm yöntemler benzer bir deseni izler. Bir film nesnesi (veya olması durumunda Indexnesne 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

Film uygulamasına iyi bir başlangıç yaptık, ancak sunu ideal değil, örneğin ReleaseDate iki sözcük olmalıdır.

Dizin görünümü: Yayın Tarihi bir sözcük (boşluk yok) ve her film yayın tarihi saat olarak 12:00'yi gösterir

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 bağlantısının üzerinde fareyle tarayıcı penceresi ve bağlantı Url'si https://localhost:5001/Movies/Edit/5 gösterilir

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.cshtmlRazor 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 sahteciliğe karşı koruma belirtecini oluşturur.

<form asp-action="Edit">

Form Etiketi Yardımcısı, Filmler denetleyicisinin yönteminde Edit oluşturulan sahtecilik önleme belirteciyle [ValidateAntiForgeryToken] eşleşmesi gereken gizli bir sahtecilik önleme 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 Movieolması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ı'nda sahte 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.

Düzenleme görünümü: Abc'nin yanlış Fiyat değeri için özel durum, Price alanının bir sayı olması gerektiğini belirtir. xyz durumlarının hatalı Yayın Tarihi değeri için özel durum Lütfen geçerli bir tarih girin.

Film denetleyicisindeki HttpGet tüm yöntemler benzer bir deseni izler. Bir film nesnesi (veya olması durumunda Indexnesne 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