Düzenleme Metotlarını ve Düzenleme Görünümünü İnceleme

Rick Anderson tarafından

Note

Bu öğreticinin güncelleştirilmiş bir sürümü, burada uygulamanın en son sürümü kullanılarak Visual Studio. Yeni öğreticide bu ASP.NET birçok geliştirme sağlayan ASP.NET Core MVC2011 1.

Bu öğreticide, ASP.NET ve görünümlere sahip çekirdek MVC'ler öğretildi. Razor Pages, web kullanıcı arabirimini daha kolay ve daha üretken bir hale ASP.NET Core'da sayfa tabanlı bir programlama modeli olan yeni bir alternatiftir. MVC sürümünden önce Razor Pages öğreticiyi denemenizi öneririz. Aşağıdaki Razor Pages öğretici:

  • 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, Edit film denetleyicisi için oluşturulan 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 göz atalım. Models\movie.cs dosyasını açın ve vurgulanan satırları aşağıda gösterildiği gibi 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; }
    }
}

Ayrıca, tarih kültürünü aşağıdakine benzer hale getirebilirsiniz:

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

Sonraki öğreticide veri ek açıklamalarını ele alacağız. Display özniteliği bir alanın adı için (Bu durumda "ReleaseDate" yerine "Yayın tarihi") görüntüleneceğini belirtir. DataType özniteliği verilerin türünü belirtir, bu durumda bir tarih olur, 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 Movies denetleyiciye gidin. Bağlantı yaptığı URL 'yi görmek için fare işaretçisini bir düzenleme bağlantısı üzerine tutun.

EditLink_sm

Düzenleme bağlantısı, Html.ActionLink Views\Movies\Index.cshtml görünümündeki yöntemi tarafından oluşturulmuştur:

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

HTML. ActionLink

HtmlNesnesi, System. Web. Mvc. WebViewPage temel sınıfında özelliği kullanılarak ortaya çıkarılan bir yardımcıdır. ActionLinkYardımcı yöntemi, denetleyicilerde eylem yöntemlerine bağlantı sağlayan HTML köprülerini dinamik olarak oluşturmayı kolaylaştırır. Yöntemin ilk bağımsız değişkeni, ActionLink işlenecek bağlantı metindir (ö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 üreten anonim bir nesnedir (Bu durumda, 4 ' ün kimliği).

Önceki görüntüde gösterilen oluşturulan bağlantı http://localhost:1234/Movies/Edit/4 . Varsayılan yol ( App _ Start\routeconfig.csIÇINDE kurulan) URL modelini alır {controller}/{action}/{id} . Bu nedenle, ASP.NET, http://localhost:1234/Movies/Edit/4 Edit denetleyicinin Action metoduna 4 ' e eşit olan bir isteğe çevirir Movies ID . Aşağıdaki kodu App _ Start\routeconfig.cs dosyasından inceleyin. MapRoute YÖNTEMI, http isteklerini doğru denetleyiciye ve eylem yöntemine yönlendirmek ve Isteğe bağlı ID parametresini sağlamak için kullanılır. MapRoute yöntemi, HtmlHelpers ActionLink Denetleyici, eylem yöntemi ve rota verileri verilen URL 'Leri oluşturmak için gibi htmlyardımcılar 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 }
    );
}

Ayrıca, bir sorgu dizesi kullanarak eylem yöntemi parametrelerini geçirebilirsiniz. Örneğin, URL http://localhost:1234/Movies/Edit?ID=3 Ayrıca ID 3 parametresini Edit denetleyicinin Action yöntemine geçirir Movies .

EditQueryString

Denetleyiciyi açın Movies . İ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ği olduğuna dikkat edin HttpPost . Bu öznitelik, yönteminin aşırı yüklemesinin Edit yalnızca post istekleri için çağrılabileceğini belirtir. HttpGetÖzniteliği ilk düzenleme yöntemine uygulayabilirsiniz, ancak varsayılan değer olduğundan bu gerekli değildir. (Özniteliği Yöntem olarak örtük olarak atanmış eylem yöntemlerine başvuracağız HttpGet HttpGet .) Bind özniteliği, korsanların modelinize veri gönderme işlemini daha fazla tutan başka önemli bir güvenlik mekanizmasıdır. Yalnızca, değiştirmek istediğiniz bağlama özniteliğinde özellikleri eklemeniz gerekir. Fazla deftere nakil ve bağlama özniteliği hakkında bilgi edinmek için bkz. fazla nakil güvenlik notum. Bu öğreticide kullanılan basit modelde, modeldeki tüm verileri bağlamamız gerekir. Validateantiforgerytoken özniteliği bir isteğin kullanımını engellemek için kullanılır ve @Html.AntiForgeryToken() düzenleme görünümü dosyasında (Views\Movies\Edit.cshtml) eşleştirilmiştir, aşağıda bir bölü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>

@Html.AntiForgeryToken() denetleyicinin yöntemiyle eşleşmesi gereken gizli form Anti-forma belirteci oluşturur Edit Movies . MVC 'de öğreticide, siteler arası istek (XSRF veya CSRF olarak da bilinir) hakkında daha fazla bilgi edinmek için bkz. MVC/CSRF önleme.

HttpGet Edit Yöntemi, film kimliği parametresini alır, Entity Framework yöntemini kullanarak filmi arar Find ve seçili filmi düzenleme görünümüne döndürür. Bir film bulunamazsa, Httpnotfound döndürülür. Scafkatlama sistemi düzenleme görünümü oluştururken, sınıfını ve Movie <label> <input> sınıfının her bir özelliği için işlenecek kodu ve öğelerini inceledi. Aşağıdaki örnekte, Visual Studio scafkatlama 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 ifadeye sahip olduğuna dikkat edin @model MvcMovie.Models.Movie ; Bu, görünümün görünüm şablonu için modelin tür olmasını beklediğini belirtir Movie .

Scafkatlanmış kod, HTML işaretlemesini kolaylaştırmak için çeşitli yardımcı yöntemler kullanır. Html.LabelForYardımcı, alanın adını ( " başlık " , " ReleaseDate " , " tarz " veya " Fiyat) görüntüler " . Html.EditorForYardımcı BIR HTML öğesi işler <input> . Html.ValidationMessageForYardımcı, bu özellikle ilişkili tüm doğrulama iletilerini görüntüler.

Uygulamayı çalıştırın ve /filmler URL 'sine gidin. Bir düzenleme bağlantısına tıklayın. Tarayıcıda, sayfanın kaynağını görüntüleyin. Form öğesi için HTML 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>

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

POST Isteği işleniyor

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

[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);
}

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

ASP.NET MVC model Ciltçi , postalanan form değerlerini alır ve Movie parametresi olarak geçirilmiş bir nesne oluşturur movie . , ModelState.IsValid Formda gönderilen verilerin bir nesneyi değiştirmek (düzenlemek veya güncelleştirmek) için kullanılabileceğini doğrular Movie . Veriler geçerliyse, film verileri Movies db ( MovieDBContext örnek) koleksiyonuna kaydedilir. Yeni film verileri, yöntemi çağırarak veritabanına kaydedilir SaveChanges MovieDBContext . Veriler kaydedildikten sonra kod, kullanıcıyı, Index MoviesController Yeni yapılan değişiklikler dahil olmak üzere, film koleksiyonunu görüntüleyen sınıfının Action yöntemine yönlendirir.

İstemci tarafı doğrulaması bir alanın değerini belirler almaz, bir hata iletisi görüntülenir. JavaScript devre dışıysa, istemci tarafı doğrulaması devre dışı bırakılır. Ancak, sunucu, gönderilen değerleri geçerli değil olarak algılar ve form değerleri hata iletileriyle birlikte görüntülenir.

Doğrulama Öğreticinin ilerleyen kısımlarında daha ayrıntılı olarak incelendi.

Html.ValidationMessageFor Edit. cshtml görünüm şablonundaki yardımcılar, uygun hata iletilerini görüntülemeyi dikkate alır.

abcNotValid

Tüm HttpGet Yöntemler benzer bir düzene uyar. Bir film nesnesi (veya bunun durumunda nesne listesi Index ) alır ve modeli görünüme iletir. CreateYöntemi, oluşturma görünümüne boş bir film nesnesi geçirir. Verileri oluşturan, düzenleme, silme veya başka bir şekilde değiştiren tüm yöntemler HttpPost , yönteminin aşırı yüküne neden olacak. HTTP GET yöntemindeki verileri değiştirmek, Web günlüğü gönderi girişi ASP.NET MVC ipucu #46 – güvenlik delikleri oluşturdukları Için silme bağlantılarını kullanmayın. GET yöntemindeki verileri değiştirmek, HTTP en iyi uygulamalarını ve bu GET isteklerinin uygulamanızın REST durumunu değiştirmemelidir. Diğer bir deyişle, bir GET işleminin gerçekleştirilmesi, yan etkileri olmayan ve kalıcı verilerinizi değiştirmeyen bir güvenli işlem olmalıdır.

Ingilizce olmayan yerel ayarlarda jQuery doğrulaması

ABD Ingilizcesi bilgisayar kullanıyorsanız, bu bölümü atlayabilir ve sonraki öğreticiye gidebilirsiniz. Bu öğreticinin globalize sürümünü buradanindirebilirsiniz. Uluslararası duruma getirme için harika iki bölüm öğreticisi için bkz. Nadeem 'ın ASP.NET MVC 5 Uluslararası duruma getirme.

Note

"ondalık bir nokta ve ABD İngilizcesi olmayan tarih biçimleri için virgül (,) kullanan İngilizce olmayan yerel ayarlarda jQuery doğrulamasını desteklemek için " , globalize.js ve belirli kültürleri/globalize.cultures.js dosyanızı (Kimden https://github.com/jquery/globalize ) ve kullanılacak JavaScript 'i dahil etmeniz gerekir Globalize.parseFloat . NuGet 'ten Ingilizce olmayan jQuery doğrulamasını alabilirsiniz. (Ingilizce yerel ayar kullanıyorsanız globalize ' yi yüklemeyin.)

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

  2. Sol bölmede, Araştır ' ı seçin *. * (Aşağıdaki resme bakın.)

  3. Giriş kutusuna * globalize * * yazın.

    Seç jQuery.Validation.Globalize ' i seçin MvcMovie ve ardından Install' a tıklayın. Scripts\jquery.globalize\globalize.js dosyası projenize eklenecektir. * Scripts\jquerypst Globalize\kültürleri * 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ındaki 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>
}

Her düzenleme görünümünde bu kodun yinelenmesinden kaçınmak için, düzen dosyasına taşıyabilirsiniz. Betik indirmeyi iyileştirmek için bkz. öğretici paketme ve küçültmeyeyönelik.

Daha fazla bilgi için bkz. ASP.NET MVC 3 Uluslararası duruma getirme ve ASP.NET MVC 3 Uluslararası duruma getirme-Bölüm 2 (nerdakşam yemeği).

Geçici bir düzeltme olarak, doğrulamanız için yerel ayarda çalışmayı alamazsanız bilgisayarınızı ABD Ingilizcesi 'ni kullanmaya zorlayabilir veya tarayıcınızda JavaScript 'ı devre dışı bırakabilirsiniz. Bilgisayarınızı ABD Ingilizcesi kullanmaya zorlamak için, proje kök web.config dosyasına Genelleştirme öğesini ekleyebilirsiniz. Aşağıdaki kod, kültürü Birleşik Devletler Ingilizce olarak ayarlanan Genelleştirme öğesini gösterir.

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

Sonraki öğreticide, arama işlevi uygulayacağız.