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ünü kullanarak bu öğreticinin güncelleştirilmiş bir sürümüne buradan ulaşabilirsiniz. Yeni öğreticide, bu öğreticide birçok geliştirme sağlayan ASP.NET Core MVC kullanılır.

Bu öğreticide, denetleyiciler ve görünümlerle ASP.NET Core MVC öğretildi. Razor Pages, web kullanıcı arabirimi oluşturmayı daha kolay ve daha üretken hale getiren sayfa tabanlı bir programlama modeli olan ASP.NET Core'de 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 saptırma yapacağız. Models\Movie.cs dosyasını açın ve aşağıda gösterilen vurgulanan 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 konularını 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 saat 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'de oluşturulur) URL desenini {controller}/{action}/{id}alır. Bu nedenle, ASP.NET 4'e eşit parametresiyle ID denetleyicinin Movies eylem yöntemine bir isteğe çevrilirhttp://localhost:1234/Movies/Edit/4.Edit 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 htmlhelpersActionLink 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 önce özniteliği olduğuna HttpPost dikkat edin. Bu öznitelik, yönteminin 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ğundan 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 fazla 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 eklemelisiniz. Fazla paylaşım ve bağlama ö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 sahtesini önlemek için kullanılır ve düzenleme görünümü dosyasında (Views\Movies\Edit.cshtml) ile @Html.AntiForgeryToken() eşleştirilir, 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 EditMovies eşleşmesi gereken gizli bir sahtecilik önleme belirteci oluşturur. MVC'de XSRF/CSRF Önleme öğreticimde Siteler arası istek sahteciliği (XSRF veya CSRF olarak da bilinir) hakkında daha fazla bilgi edinebilirsiniz.

HttpGetEdit yöntemi film kimliği parametresini alır, Entity Framework Find yöntemini kullanarak filmi arar ve seçili filmi Düzenleme 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> öğesini 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 /Movies 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> öğesindediraction. 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 görüntülenir.

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

Html.ValidationMessageForEdit.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 olması durumunda Indexnesne listesi) 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, silip 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, MVC İpucu #46 ASP.NET blog gönderisi girdisinde açıklandığı gibi bir güvenlik riskidir . Güvenlik Açıkları oluşturdukları için Bağlantıları Sil'i kullanmayın. 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ı

US-English bilgisayar kullanıyorsanız, bu bölümü atlayabilir ve sonraki öğreticiye gidebilirsiniz. Bu öğreticinin Globalize 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 US-English olmayan tarih biçimleri kullanan İngilizce olmayan yerel ayarlarda jQuery doğrulamasını desteklemek için, kullanmak Globalize.parseFloatüzere globalize.js ve belirli kültürlerinizi/globalize.cultures.js dosyanızı(kimden https://github.com/jquery/globalize ) ve JavaScript'i eklemeniz gerekir. NuGet'ten İngilizce olmayan jQuery doğrulamasını alabilirsiniz. (İngilizce yerel ayar kullanıyorsanız Globalize'ı yüklemeyin.)

  1. Araçlar menüsünde NuGet Paket Yöneticisi'ne 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çin jQuery.Validation.Globalize, seçin MvcMovie ve Yükle'ye tıklayın. Scripts\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üklenmesinin beş dakika sürebileceğini unutmayın.

    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 yinelenmesinden kaçınmak için, kodu düzen dosyasına taşıyabilirsiniz. Betik indirmeyi iyileştirmek için bkz. Bundling ve Minification öğreticim.

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

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, genelleştirme öğesini projelerin kök web.config dosyasına ekleyebilirsiniz. Aşağıdaki kod, kültürün İngilizce Birleşik Devletler olarak ayarlandığı genelleştirme öğesini gösterir.

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

Sonraki öğreticide arama işlevini uygulayacağız.