Film Denetleyicisi için Eylem Yöntemlerini ve Görünümlerini Düzenlemeyi İnceleme

tarafından Rick Anderson

Not

Visual Studio'nun en son sürümü kullanılarak bu öğreticinin güncelleştirilmiş bir sürümü burada kullanılabilir. Yeni öğreticide, bu öğretici üzerinde birçok geliştirme sağlayan ASP.NET Core MVC ağlanmaktadır.

Bu öğreticide ASP.NET Core MVC'ye denetleyiciler ve görünümler öğretildi. Razor Pages, web kullanıcı arabirimi oluşturmayı kolaylaştıran ve daha üretken hale getiren sayfa tabanlı bir programlama modeli olan ASP.NET Core'daki yeni bir alternatiftir. Razor Pages öğreticisini MVC sürümünden önce denemenizi öneririz. Razor Pages öğreticisi:

  • Takip etmek daha kolaydır.
  • Daha fazla özelliği kapsar.
  • Yeni uygulama geliştirme için tercih edilen yaklaşımdır.

Bu bölümde, film denetleyicisi için oluşturulan Edit eylem yöntemlerini ve görünümlerini inceleyeceksiniz. Ancak ilk olarak yayın tarihinin daha iyi görünmesini sağlamak için kısa bir sapma yapacağız. Models\Movie.cs dosyasını açın ve aşağıda gösterilen vurgulanmış satırları ekleyin:

using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;

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

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }
        public decimal Price { get; set; }
    }

    public class MovieDBContext : DbContext
    {
        public DbSet<Movie> Movies { get; set; }
    }
}

Tarih kültürünü de şuna özgü hale getirebilirsiniz:

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { 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ü belirtir; bu durumda bu bir tarihtir, bu nedenle alanda depolanan zaman bilgileri görüntülenmez. Chrome tarayıcısında tarih biçimlerini yanlış işleyen bir hata için DisplayFormat özniteliği gereklidir.

Uygulamayı çalıştırın ve denetleyiciye Movies göz atın. Bağlandığını URL'yi görmek için fare işaretçisini Düzenle bağlantısının üzerinde tutun.

EditLink_sm

Düzenle bağlantısı Views\Movies\Index.cshtml görünümünde yöntemi tarafından Html.ActionLink oluşturuldu:

@Html.ActionLink("Edit", "Edit", new { id=item.ID })

Html.ActionLink

Html nesnesi, System.Web.Mvc.WebViewPage temel sınıfındaki bir özellik kullanılarak kullanıma sunulan bir yardımcıdır. ActionLink Yardımcının yöntemi, denetleyicilerdeki eylem yöntemlerine bağlanan HTML köprülerini dinamik olarak oluşturmayı kolaylaştırır. yönteminin ActionLink ilk bağımsız değişkeni, işlenmek üzere bağlantı metnidir (örneğin, <a>Edit Me</a>). İkinci bağımsız değişken, çağrılacak eylem yönteminin adıdır (Bu durumda, Edit eylem). Son bağımsız değişken, yol verilerini oluşturan anonim bir nesnedir (bu örnekte 4 kimliği).

Önceki görüntüde gösterilen oluşturulan bağlantı şeklindedir http://localhost:1234/Movies/Edit/4. Varsayılan yol (App_Start\RouteConfig.cs'da kurulan) URL desenini {controller}/{action}/{id}alır. Bu nedenle, ASP.NET parametresi 4'e Edit eşit olan denetleyicinin Movies eylem yöntemine bir isteğe çevrilirhttp://localhost:1234/Movies/Edit/4.ID App_Start\RouteConfig.cs dosyasından aşağıdaki kodu inceleyin. MapRoute yöntemi, HTTP isteklerini doğru denetleyiciye ve eylem yöntemine yönlendirmek ve isteğe bağlı kimlik parametresini sağlamak için kullanılır. MapRoute yöntemi, denetleyici, eylem yöntemi ve herhangi bir yol verisi verildiğinde URL'ler oluşturmak için HtmlHelpers ActionLink tarafından da kullanılır.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", 
            id = UrlParameter.Optional }
    );
}

Sorgu dizesini kullanarak eylem yöntemi parametrelerini de geçirebilirsiniz. Örneğin, URL http://localhost:1234/Movies/Edit?ID=3 3 parametresini ID denetleyicinin Edit eylem yöntemine Movies de geçirir.

EditQueryString

Denetleyiciyi Movies açın. İki Edit eylem yöntemi aşağıda gösterilmiştir.

// GET: /Movies/Edit/5
public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

// POST: /Movies/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (ModelState.IsValid)
    {
        db.Entry(movie).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(movie);
}

İkinci Edit eylem yönteminin önünde özniteliğinin HttpPost olduğuna dikkat edin. Bu öznitelik, yöntemin aşırı yüklemesinin Edit yalnızca POST istekleri için çağrılabileceğini belirtir. özniteliğini HttpGet ilk düzenleme yöntemine uygulayabilirsiniz, ancak varsayılan olduğu için bu gerekli değildir. (Özniteliği örtük olarak yöntem olarak HttpGet atanmış eylem yöntemlerine HttpGet başvuracağız.) Bind özniteliği, bilgisayar korsanlarının modelinize aşırı veri göndermesini engelleyen bir diğer önemli güvenlik mekanizmasıdır. Bağlama özniteliğine yalnızca değiştirmek istediğiniz özellikleri eklemeniz gerekir. Overposting ve bind özniteliği hakkında bilgi edinmek için üst paylaşım güvenlik notumu kullanabilirsiniz. Bu öğreticide kullanılan basit modelde modeldeki tüm verileri bağlayacağız. ValidateAntiForgeryToken özniteliği, bir isteğin sahte olmasını önlemek için kullanılır ve düzenleme görünümü dosyasında (Views\Movies\Edit.cshtml) ile eşleştirilir@Html.AntiForgeryToken(), aşağıda bir bölüm gösterilir:

@model MvcMovie.Models.Movie

@{
    ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()    
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.ID)

        <div class="form-group">
            @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Title)
                @Html.ValidationMessageFor(model => model.Title)
            </div>
        </div>

@Html.AntiForgeryToken() , denetleyicinin yönteminde Edit Movies eşleşmesi gereken gizli bir sahteciliğe karşı koruma belirteci oluşturur. MVC'de XSRF/CSRF Önleme öğreticimdeki Siteler arası istek sahteciliği (XSRF veya CSRF olarak da bilinir) hakkında daha fazla bilgi edinebilirsiniz.

HttpGet Edit yöntemi film kimliği parametresini alır, Entity Framework Find yöntemini kullanarak filmi arar ve seçili filmi Düzenle görünümüne döndürür. Bir film bulunamazsa HttpNotFound döndürülür. 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

@{
    ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()    
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.ID)

        <div class="form-group">
            @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Title)
                @Html.ValidationMessageFor(model => model.Title)
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.ReleaseDate, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ReleaseDate)
                @Html.ValidationMessageFor(model => model.ReleaseDate)
            </div>
        </div>
        @*Genre and Price 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>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Görünüm şablonunun dosyanın en üstünde bir @model MvcMovie.Models.Movie deyimi olduğuna dikkat edin; bu, görünümün görünüm şablonu için modelin türünde Movieolmasını beklediğini belirtir.

yapı iskelesi oluşturulmuş kod, HTML işaretlemesini kolaylaştırmak için çeşitli yardımcı yöntemler kullanır. Yardımcı, Html.LabelFor alanın adını ("Title", "ReleaseDate", "Genre" veya "Price") görüntüler. Yardımcı Html.EditorFor bir HTML <input> öğesi işler. Yardımcı, Html.ValidationMessageFor bu özellik ile ilişkili tüm doğrulama iletilerini görüntüler.

Uygulamayı çalıştırın ve /Filmler URL'sine gidin. Düzenle bağlantısına tıklayın. Tarayıcıda sayfanın kaynağını görüntüleyin. Form öğesinin HTML'i aşağıda gösterilmiştir.

<form action="/movies/Edit/4" method="post">
   <input name="__RequestVerificationToken" type="hidden" value="UxY6bkQyJCXO3Kn5AXg-6TXxOj6yVBi9tghHaQ5Lq_qwKvcojNXEEfcbn-FGh_0vuw4tS_BRk7QQQHlJp8AP4_X4orVNoQnp2cd8kXhykS01" />  <fieldset class="form-horizontal">
      <legend>Movie</legend>

      <input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="4" />

      <div class="control-group">
         <label class="control-label" for="Title">Title</label>
         <div class="controls">
            <input class="text-box single-line" id="Title" name="Title" type="text" value="GhostBusters" />
            <span class="field-validation-valid help-inline" data-valmsg-for="Title" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="control-group">
         <label class="control-label" for="ReleaseDate">Release Date</label>
         <div class="controls">
            <input class="text-box single-line" data-val="true" data-val-date="The field Release Date must be a date." data-val-required="The Release Date field is required." id="ReleaseDate" name="ReleaseDate" type="date" value="1/1/1984" />
            <span class="field-validation-valid help-inline" data-valmsg-for="ReleaseDate" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="control-group">
         <label class="control-label" for="Genre">Genre</label>
         <div class="controls">
            <input class="text-box single-line" id="Genre" name="Genre" type="text" value="Comedy" />
            <span class="field-validation-valid help-inline" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="control-group">
         <label class="control-label" for="Price">Price</label>
         <div class="controls">
            <input class="text-box single-line" 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" type="text" value="7.99" />
            <span class="field-validation-valid help-inline" data-valmsg-for="Price" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="form-actions no-color">
         <input type="submit" value="Save" class="btn" />
      </div>
   </fieldset>
</form>

Öğeler<input>, özniteliği /Movies/Edit URL'sine gönderi olarak ayarlanmış bir HTML <form> öğesindedir action . Kaydet düğmesine tıklandığında form verileri sunucuya gönderilir. İkinci satır, çağrı tarafından oluşturulan gizli XSRF belirtecini @Html.AntiForgeryToken() gösterir.

POST İsteğini İşleme

Aşağıdaki listede eylem yönteminin Edit sürümü gösterilmektedirHttpPost.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (ModelState.IsValid)
    {
        db.Entry(movie).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(movie);
}

ValidateAntiForgeryToken özniteliği, görünümdeki çağrı tarafından oluşturulan XSRF belirtecini @Html.AntiForgeryToken() doğrular.

ASP.NET MVC model bağlayıcısı, gönderilen form değerlerini alır ve parametre olarak movie geçirilen bir Movie nesne oluşturur. , 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, film verileri (MovieDBContext örneğininMovies) koleksiyonuna dbkaydedilir. Yeni film verileri, yöntemini MovieDBContextçağırarak SaveChanges 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.

İstemci tarafı doğrulaması bir alanın değerinin geçerli olmadığını belirlediği anda bir hata iletisi görüntülenir. JavaScript devre dışı bırakılırsa istemci tarafı doğrulaması devre dışı bırakılır. Ancak, sunucu gönderilen değerlerin geçerli olmadığını algılar ve form değerleri hata iletileriyle yeniden dağıtılır.

Doğrulama, öğreticinin ilerleyen bölümlerinde daha ayrıntılı olarak incelendi.

Html.ValidationMessageFor Edit.cshtml görünüm şablonundaki yardımcılar uygun hata iletilerinin görüntülenmesini sağlar.

abcNotValid

HttpGet Tüm yöntemler benzer bir desen izler. Bir film nesnesi (veya nesne Indexlistesi) alır ve modeli görünüme geçirir. yöntemi, Create boş bir film nesnesini Oluştur görünümüne 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. HTTP GET yöntemindeki verileri değiştirmek bir güvenlik riskidir. GET yöntemindeki verilerin değiştirilmesi, HTTP en iyi yöntemlerini ve GET isteklerinin uygulamanızın durumunu değiştirmemesi gerektiğini belirten mimari REST desenini 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.

İngilizce olmayan yerel ayarlar için jQuery doğrulaması

ABD İngilizcesi bilgisayar kullanıyorsanız, bu bölümü atlayabilir ve sonraki öğreticiye gidebilirsiniz. Bu öğreticinin Genelleştir sürümünü buradan indirebilirsiniz. Uluslararasılaştırma hakkında mükemmel bir iki bölüm öğreticisi için bkz . Nadeem'in ASP.NET MVC 5 Uluslararasılaştırması.

Not

ondalık ayırıcı için virgül (",") ve ABD İngilizcesi olmayan tarih biçimleri kullanan İngilizce olmayan yerel ayarlar için jQuery doğrulamasını desteklemek için, kullanmak Globalize.parseFloatüzere globalize.js ve belirli kültürlerinizi/globalize.cultures.js dosyanızı('dan https://github.com/jquery/globalize ) ve JavaScript'i eklemeniz gerekir. İngilizce olmayan jQuery doğrulamasını NuGet'ten alabilirsiniz. (İngilizce yerel ayar kullanıyorsanız Globalize'ı yüklemeyin.)

  1. Araçlar menüsünde NuGet Paket Yöneticisi'e tıklayın ve ardından Çözüm için NuGet Paketlerini Yönet'e tıklayın.

    İngilizce olmayan yerel ayarlar için jQuery doğrulamasını başlatmak için Araçlar menüsünün ekran görüntüsü.

  2. Sol bölmede Gözat*'ı seçin .*(Aşağıdaki resme bakın.)

  3. Giriş kutusuna Genelleştir* yazın.

    Genelleştir'e girmek için giriş kutusunun ekran görüntüsü.

    öğesini seçinjQuery.Validation.Globalize, seçin MvcMovie ve Yükle'ye tıklayın. Script\jquery.globalize\globalize.js dosyası projenize eklenir. *Scripts\jquery.globalize\cultures* klasörü birçok kültür JavaScript dosyası içerir. Bu paketin yüklenmesi beş dakika sürebilir.

    Aşağıdaki kod Views\Movies\Edit.cshtml dosyasında yapılan değişiklikleri gösterir:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")

<script src="~/Scripts/globalize/globalize.js"></script>
<script src="~/Scripts/globalize/cultures/globalize.culture.@(System.Threading.Thread.CurrentThread.CurrentCulture.Name).js"></script>
<script>
    $.validator.methods.number = function (value, element) {
        return this.optional(element) ||
            !isNaN(Globalize.parseFloat(value));
    }
    $(document).ready(function () {
        Globalize.culture('@(System.Threading.Thread.CurrentThread.CurrentCulture.Name)');
    });
</script>
<script>
    jQuery.extend(jQuery.validator.methods, {
        range: function (value, element, param) {
            //Use the Globalization plugin to parse the value
            var val = Globalize.parseFloat(value);
            return this.optional(element) || (
                val >= param[0] && val <= param[1]);
        }
    });
    $.validator.methods.date = function (value, element) {
        return this.optional(element) ||
            Globalize.parseDate(value) ||
            Globalize.parseDate(value, "yyyy-MM-dd");
    }
</script>
}

Bu kodun her Düzenleme görünümünde yinelenmemesi için, kodu düzen dosyasına taşıyabilirsiniz. Betik indirmeyi iyileştirmek için bkz. Öğretici Paketleme ve Küçültme.

Daha fazla bilgi için bkz . MVC 3 Uluslararasılaştırma ve ASP.NET MVC 3 Uluslararasılaştırma - Bölüm 2 (NerdDinner) ASP.NET.

Geçici bir düzeltme olarak, yerel ayarınızda doğrulamayı çalıştıramıyorsanız bilgisayarınızı ABD İngilizcesi kullanmaya zorlayabilir veya tarayıcınızda JavaScript'i devre dışı bırakabilirsiniz. Bilgisayarınızı ABD İngilizcesi kullanmaya zorlamak için projelerin kök web.config dosyasına genelleştirme öğesini ekleyebilirsiniz. Aşağıdaki kod, kültürü İngilizce Birleşik Devletler olarak ayarlanmış genelleştirme öğesini gösterir.

<system.web>
    <globalization culture ="en-US" />
    <!--elements removed for clarity-->
  </system.web>

Sonraki öğreticide arama işlevselliğini uygulayacağız.