Bölüm 3, ASP.NET Core'da yapı iskelesi oluşturulmuş Razor Sayfalar

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

Bu öğreticide, önceki öğreticide Razoryapı iskelesi tarafından oluşturulan Sayfalar incelenir.

Oluştur, Sil, Ayrıntılar ve Düzenle sayfaları

Pages/Movies/Index.cshtml.cs Sayfa Modelini İnceleme:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies;

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

    public IList<Movie> Movie { get;set; }  = default!;

    public async Task OnGetAsync()
    {
        if (_context.Movie != null)
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Razor Sayfalar' dan PageModeltüretilir. Kurala PageModel göre, türetilmiş sınıf olarak adlandırılır PageNameModel. Örneğin, Dizin sayfası olarak adlandırılır IndexModel.

Oluşturucu, öğesini sayfaya eklemek RazorPagesMovieContext için bağımlılık ekleme işlemini kullanır:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Entity Framework ile zaman uyumsuz programlama hakkında daha fazla bilgi için bkz . Zaman uyumsuz kod .

Sayfa için istekte GET bulunulduğunda, OnGetAsync yöntemi Sayfaya Razor bir film listesi döndürür. Bir Razor Sayfada OnGetAsync veya OnGet sayfanın durumunu başlatmak için çağrılır. Bu durumda, OnGetAsync filmlerin bir listesini alır ve görüntüler.

döndürdüğünde OnGetvoid veya OnGetAsync döndürdüğünde Task, return deyimi kullanılmaz. Örneğin, Sayfayı Privacy inceleyin:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesMovie.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

dönüş türü veya Task<IActionResult>olduğundaIActionResult, bir return deyimi sağlanmalıdır. Örneğin, Pages/Movies/Create.cshtml.cs OnPostAsync yöntemi:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Sayfayı Pages/Movies/Index.cshtmlRazor inceleyin:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor HTML'den C# veya özel işaretlemeye Razorgeçiş yapabilir. Bir @ simgenin ardından ayrılmış anahtar Razor sözcük geçtiğinde, özel işaretlemeye Razor, aksi takdirde C# işaretine geçirilir.

yönergesi @page

yönergesi @pageRazor , dosyayı MVC eylemi yapar ve bu da istekleri işleyebileceği anlamına gelir. @page, sayfadaki ilk Razor yönergesi olmalıdır. @page ve @model özel işaretlemeye geçiş Razorörnekleridir. Daha fazla bilgi için söz dizimine bakınRazor.

yönergesi @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

yönergesi @model , Sayfaya geçirilen modelin Razor türünü belirtir. Yukarıdaki örnekte, @model satır türetilmiş sınıfı Sayfa için Razor kullanılabilir hale getirirPageModel. Model, sayfadaki ve @Html.DisplayForHTML Yardımcıları'nda @Html.DisplayNameFor kullanılır.

Aşağıdaki HTML Yardımcısı'nda kullanılan lambda ifadesini inceleyin:

@Html.DisplayNameFor(model => model.Movie[0].Title)

HTML Yardımcısı, DisplayNameFor görünen adı belirlemek için lambda ifadesinde başvuruda bulunan özelliği inceler Title . Lambda ifadesi değerlendirilmek yerine incelenir. Bu, , model.Movieveya olduğunda veya nullmodel.Movie[0] boş olduğunda modelerişim ihlali olmadığı anlamına gelir. Lambda ifadesi, örneğin ile @Html.DisplayFor(modelItem => item.Title)değerlendirildiğinde modelin özellik değerleri değerlendirilir.

Düzen sayfası

PagesMovie, Homeve Privacymenü bağlantılarını Razorseçin. Her sayfada aynı menü düzeni gösterilir. Menü düzeni dosyasında uygulanır Pages/Shared/_Layout.cshtml .

Dosyasını açın ve inceleyin Pages/Shared/_Layout.cshtml .

Düzen şablonları, HTML kapsayıcı düzeninin şu şekilde olmasını sağlar:

  • Tek bir yerde belirtilir.
  • Sitedeki birden çok sayfaya uygulanır.

@RenderBody() Satırı bulun. RenderBody , sayfaya özgü tüm görünümlerin düzen sayfasında sarmalandığı bir yer tutucudur. Örneğin, bağlantıyı Pages/Privacy.cshtml seçtiğinizde Privacy görünüm yöntemi içinde RenderBody işlenir.

ViewData ve düzen

Dosyadan aşağıdaki işaretlemeyi Pages/Movies/Index.cshtml göz önünde bulundurun:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Yukarıdaki vurgulanmış işaretleme, C# içine geçiş örneğidir Razor . { ve } karakterleri bir C# kodu bloğunu içine alır.

PageModel Temel sınıf, bir ViewData Görünüme veri geçirmek için kullanılabilecek bir sözlük özelliği içerir. Nesneler anahtar değeri deseni ViewData kullanılarak sözlüğe eklenir. Yukarıdaki örnekte özelliği Title sözlüğe eklenir ViewData .

Title özelliği dosyasında kullanılırPages/Shared/_Layout.cshtml. Aşağıdaki işaretlemede dosyanın ilk birkaç satırı gösterilmektedir _Layout.cshtml .

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/RazorPagesMovie.styles.css" asp-append-version="true" />

Düzeni güncelleştirme

  1. <title> Dosyadaki Pages/Shared/_Layout.cshtml öğesini PagesMovie yerineRazor Movie görüntüleyecek şekilde değiştirin.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. Dosyasında aşağıdaki tutturucu öğesini Pages/Shared/_Layout.cshtml bulun.

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Önceki öğeyi aşağıdaki işaretlemeyle değiştirin:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Yukarıdaki yer işareti öğesi bir Etiket Yardımcısı'dır. Bu durumda, Tutturucu Etiketi Yardımcısı'dır. asp-page="/Movies/Index" Etiket Yardımcısı özniteliği ve değeri Sayfaya /Movies/IndexRazor bir bağlantı oluşturur. asp-area Öznitelik değeri boş olduğundan, alan bağlantıda kullanılmaz. Daha fazla bilgi için bkz . Alanlar .

  4. Değişiklikleri kaydedin ve RpMovie bağlantısını seçerek uygulamayı test edin. Herhangi bir sorun yaşıyorsanız GitHub'daki _Layout.cshtml dosyasına bakın.

  5. Home, RpMovie, Oluştur, Düzenle ve Sil bağlantılarını test edin. Her sayfa, tarayıcı sekmesinde görebileceğiniz başlığı ayarlar. Sayfaya yer işareti eklediğinizde, başlık yer işareti için kullanılır.

Not

Alana ondalık virgül Price giremeyebilirsiniz. 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 uygulamayı genelleştirmek için adımlar uygulamanız gerekir. Ondalık virgül ekleme yönergeleri için bu GitHub sorunu 4076'ya bakın.

Layout özelliği dosyasında ayarlanırPages/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Yukarıdaki işaretleme, Sayfalar klasörünün altındaki tüm Razor dosyalar için düzen dosyasını Pages/Shared/_Layout.cshtml olarak ayarlar. Daha fazla bilgi için bkz . Düzen .

Sayfa oluştur modeli

Pages/Movies/Create.cshtml.cs Sayfa modelini inceleyin:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; } = default!;
        

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
          if (!ModelState.IsValid || _context.Movie == null || Movie == null)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

yöntemi, OnGet sayfa için gereken tüm durumları başlatır. Oluştur sayfasının başlatacak Page bir durumu olmadığından döndürülür. Öğreticinin ilerleyen bölümlerinde durumu başlatma örneği OnGet gösterilir. yöntemi, Page sayfayı Create.cshtml işleyen bir PageResult nesne oluşturur.

özelliği, Movie model bağlamayı kabul etmek için [BindProperty] özniteliğini kullanır. Oluştur formu form değerlerini gönderdiğinde, ASP.NET Core çalışma zamanı deftere nakledilen değerleri modele Movie bağlar.

Yöntemi OnPostAsync , sayfa form verilerini gönderirken çalıştırılır:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Herhangi bir model hatası varsa form, gönderilen form verileriyle birlikte yeniden dağıtılır. Çoğu model hatası, form gönderilmeden önce istemci tarafında yakalanabilir. Model hatasına örnek olarak tarih alanı için tarihe dönüştürülemeyen bir değer gönderilebilir. İstemci tarafı doğrulama ve model doğrulaması öğreticinin ilerleyen bölümlerinde ele alınmalıdır.

Model hatası yoksa:

  • Veriler kaydedilir.
  • Tarayıcı Dizin sayfasına yönlendirilir.

Oluştur Razor Sayfası

Pages/Movies/Create.cshtmlRazor Sayfa dosyasını inceleyin:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio, Etiket Yardımcıları için kullanılan ayırt edici bir kalın yazı tipinde aşağıdaki etiketleri görüntüler:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <label asp-for="Movie.Title" class="control-label"></label>
  • <input asp-for="Movie.Title" class="form-control" />
  • <span asp-validation-for="Movie.Title" class="text-danger"></span>

Create.cshtml sayfasının VS17 görünümü

<form method="post"> öğesi bir Form Etiketi Yardımcısı'dır. Form Etiketi Yardımcısı otomatik olarak bir kötü amaçlı yazılımdan koruma belirteci içerir.

yapı iskelesi altyapısı, modeldeki her alan için kimlik dışında aşağıdakine benzer bir işaretleme oluşturur Razor :

<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
    <label asp-for="Movie.Title" class="control-label"></label>
    <input asp-for="Movie.Title" class="form-control" />
    <span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>

Doğrulama Etiketi Yardımcıları (<div asp-validation-summary ve <span asp-validation-for) doğrulama hatalarını görüntüler. Doğrulama, bu serinin ilerleyen bölümlerinde daha ayrıntılı olarak ele alınmıştır.

Etiket Etiketi Yardımcısı (<label asp-for="Movie.Title" class="control-label"></label>), özelliği için etiket başlık ve [for] özniteliğini Title oluşturur.

Giriş Etiketi Yardımcısı (<input asp-for="Movie.Title" class="form-control">), DataAnnotations özniteliklerini kullanır ve istemci tarafında jQuery Doğrulaması için gereken HTML özniteliklerini üretir.

gibi <form method="post">Etiket Yardımcıları hakkında daha fazla bilgi için bkz . ASP.NET Core'da Etiket Yardımcıları.

Sonraki adımlar

Oluştur, Sil, Ayrıntılar ve Düzenle sayfaları

Pages/Movies/Index.cshtml.cs Sayfa Modelini İnceleme:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies;

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

    public IList<Movie> Movie { get;set; }  = default!;

    public async Task OnGetAsync()
    {
        if (_context.Movie != null)
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Razor Sayfalar' dan PageModeltüretilir. Kurala PageModel göre, türetilmiş sınıf olarak adlandırılır PageNameModel. Örneğin, Dizin sayfası olarak adlandırılır IndexModel.

Oluşturucu, öğesini sayfaya eklemek RazorPagesMovieContext için bağımlılık ekleme işlemini kullanır:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Entity Framework ile zaman uyumsuz programlama hakkında daha fazla bilgi için bkz . Zaman uyumsuz kod .

Sayfa için istekte GET bulunulduğunda, OnGetAsync yöntemi Sayfaya Razor bir film listesi döndürür. Bir Razor Sayfada OnGetAsync veya OnGet sayfanın durumunu başlatmak için çağrılır. Bu durumda, OnGetAsync filmlerin bir listesini alır ve görüntüler.

döndürdüğünde OnGetvoid veya OnGetAsync döndürdüğünde Task, return deyimi kullanılmaz. Örneğin, Sayfayı Privacy inceleyin:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesMovie.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

dönüş türü veya Task<IActionResult>olduğundaIActionResult, bir return deyimi sağlanmalıdır. Örneğin, Pages/Movies/Create.cshtml.cs OnPostAsync yöntemi:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Sayfayı Pages/Movies/Index.cshtmlRazor inceleyin:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor HTML'den C# veya özel işaretlemeye Razorgeçiş yapabilir. Bir @ simgenin ardından ayrılmış anahtar Razor sözcük geçtiğinde, özel işaretlemeye Razor, aksi takdirde C# işaretine geçirilir.

yönergesi @page

yönergesi @pageRazor , dosyayı MVC eylemi yapar ve bu da istekleri işleyebileceği anlamına gelir. @page, sayfadaki ilk Razor yönergesi olmalıdır. @page ve @model özel işaretlemeye geçiş Razorörnekleridir. Daha fazla bilgi için söz dizimine bakınRazor.

yönergesi @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

yönergesi @model , Sayfaya geçirilen modelin Razor türünü belirtir. Yukarıdaki örnekte, @model satır türetilmiş sınıfı Sayfa için Razor kullanılabilir hale getirirPageModel. Model, sayfadaki ve @Html.DisplayForHTML Yardımcıları'nda @Html.DisplayNameFor kullanılır.

Aşağıdaki HTML Yardımcısı'nda kullanılan lambda ifadesini inceleyin:

@Html.DisplayNameFor(model => model.Movie[0].Title)

HTML Yardımcısı, DisplayNameFor görünen adı belirlemek için lambda ifadesinde başvuruda bulunan özelliği inceler Title . Lambda ifadesi değerlendirilmek yerine incelenir. Bu, , model.Movieveya olduğunda veya nullmodel.Movie[0] boş olduğunda modelerişim ihlali olmadığı anlamına gelir. Lambda ifadesi, örneğin ile @Html.DisplayFor(modelItem => item.Title)değerlendirildiğinde modelin özellik değerleri değerlendirilir.

Düzen sayfası

PagesMovie, Homeve Privacymenü bağlantılarını Razorseçin. Her sayfada aynı menü düzeni gösterilir. Menü düzeni dosyasında uygulanır Pages/Shared/_Layout.cshtml .

Dosyasını açın ve inceleyin Pages/Shared/_Layout.cshtml .

Düzen şablonları, HTML kapsayıcı düzeninin şu şekilde olmasını sağlar:

  • Tek bir yerde belirtilir.
  • Sitedeki birden çok sayfaya uygulanır.

@RenderBody() Satırı bulun. RenderBody , sayfaya özgü tüm görünümlerin düzen sayfasında sarmalandığı bir yer tutucudur. Örneğin, bağlantıyı Pages/Privacy.cshtml seçtiğinizde Privacy görünüm yöntemi içinde RenderBody işlenir.

ViewData ve düzen

Dosyadan aşağıdaki işaretlemeyi Pages/Movies/Index.cshtml göz önünde bulundurun:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Yukarıdaki vurgulanmış işaretleme, C# içine geçiş örneğidir Razor . { ve } karakterleri bir C# kodu bloğunu içine alır.

PageModel Temel sınıf, bir ViewData Görünüme veri geçirmek için kullanılabilecek bir sözlük özelliği içerir. Nesneler anahtar değeri deseni ViewData kullanılarak sözlüğe eklenir. Yukarıdaki örnekte özelliği Title sözlüğe eklenir ViewData .

Title özelliği dosyasında kullanılırPages/Shared/_Layout.cshtml. Aşağıdaki işaretlemede dosyanın ilk birkaç satırı gösterilmektedir _Layout.cshtml .

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/RazorPagesMovie.styles.css" asp-append-version="true" />

Satır @*Markup removed for brevity.*@ bir Razor açıklamadır. HTML açıklamalarının <!-- -->aksine, Razor açıklamalar istemciye gönderilmez. Daha fazla bilgi için bkz . MDN web belgeleri: HTML kullanmaya başlama.

Düzeni güncelleştirme

  1. <title> Dosyadaki Pages/Shared/_Layout.cshtml öğesini PagesMovie yerineRazor Movie görüntüleyecek şekilde değiştirin.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. Dosyasında aşağıdaki tutturucu öğesini Pages/Shared/_Layout.cshtml bulun.

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Önceki öğeyi aşağıdaki işaretlemeyle değiştirin:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Yukarıdaki yer işareti öğesi bir Etiket Yardımcısı'dır. Bu durumda, Tutturucu Etiketi Yardımcısı'dır. asp-page="/Movies/Index" Etiket Yardımcısı özniteliği ve değeri Sayfaya /Movies/IndexRazor bir bağlantı oluşturur. asp-area Öznitelik değeri boş olduğundan, alan bağlantıda kullanılmaz. Daha fazla bilgi için bkz . Alanlar .

  4. Değişiklikleri kaydedin ve RpMovie bağlantısını seçerek uygulamayı test edin. Herhangi bir sorun yaşıyorsanız GitHub'daki _Layout.cshtml dosyasına bakın.

  5. Home, RpMovie, Oluştur, Düzenle ve Sil bağlantılarını test edin. Her sayfa, tarayıcı sekmesinde görebileceğiniz başlığı ayarlar. Sayfaya yer işareti eklediğinizde, başlık yer işareti için kullanılır.

Not

Alana ondalık virgül Price giremeyebilirsiniz. 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 uygulamayı genelleştirmek için adımlar uygulamanız gerekir. Ondalık virgül ekleme yönergeleri için bu GitHub sorunu 4076'ya bakın.

Layout özelliği dosyasında ayarlanırPages/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Yukarıdaki işaretleme, Sayfalar klasörünün altındaki tüm Razor dosyalar için düzen dosyasını Pages/Shared/_Layout.cshtml olarak ayarlar. Daha fazla bilgi için bkz . Düzen .

Sayfa oluştur modeli

Pages/Movies/Create.cshtml.cs Sayfa modelini inceleyin:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; } = default!;
        

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
          if (!ModelState.IsValid || _context.Movie == null || Movie == null)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

yöntemi, OnGet sayfa için gereken tüm durumları başlatır. Oluştur sayfasının başlatacak Page bir durumu olmadığından döndürülür. Öğreticinin ilerleyen bölümlerinde durumu başlatma örneği OnGet gösterilir. yöntemi, Page sayfayı Create.cshtml işleyen bir PageResult nesne oluşturur.

özelliği, Movie model bağlamayı kabul etmek için [BindProperty] özniteliğini kullanır. Oluştur formu form değerlerini gönderdiğinde, ASP.NET Core çalışma zamanı deftere nakledilen değerleri modele Movie bağlar.

Yöntemi OnPostAsync , sayfa form verilerini gönderirken çalıştırılır:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Herhangi bir model hatası varsa form, gönderilen form verileriyle birlikte yeniden dağıtılır. Çoğu model hatası, form gönderilmeden önce istemci tarafında yakalanabilir. Model hatasına örnek olarak tarih alanı için tarihe dönüştürülemeyen bir değer gönderilebilir. İstemci tarafı doğrulama ve model doğrulaması öğreticinin ilerleyen bölümlerinde ele alınmalıdır.

Model hatası yoksa:

  • Veriler kaydedilir.
  • Tarayıcı Dizin sayfasına yönlendirilir.

Oluştur Razor Sayfası

Pages/Movies/Create.cshtmlRazor Sayfa dosyasını inceleyin:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio, Etiket Yardımcıları için kullanılan ayırt edici bir kalın yazı tipinde aşağıdaki etiketleri görüntüler:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <label asp-for="Movie.Title" class="control-label"></label>
  • <input asp-for="Movie.Title" class="form-control" />
  • <span asp-validation-for="Movie.Title" class="text-danger"></span>

Create.cshtml sayfasının VS17 görünümü

<form method="post"> öğesi bir Form Etiketi Yardımcısı'dır. Form Etiketi Yardımcısı otomatik olarak bir kötü amaçlı yazılımdan koruma belirteci içerir.

yapı iskelesi altyapısı, modeldeki her alan için kimlik dışında aşağıdakine benzer bir işaretleme oluşturur Razor :

<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
    <label asp-for="Movie.Title" class="control-label"></label>
    <input asp-for="Movie.Title" class="form-control" />
    <span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>

Doğrulama Etiketi Yardımcıları (<div asp-validation-summary ve <span asp-validation-for) doğrulama hatalarını görüntüler. Doğrulama, bu serinin ilerleyen bölümlerinde daha ayrıntılı olarak ele alınmıştır.

Etiket Etiketi Yardımcısı (<label asp-for="Movie.Title" class="control-label"></label>), özelliği için etiket başlık ve [for] özniteliğini Title oluşturur.

Giriş Etiketi Yardımcısı (<input asp-for="Movie.Title" class="form-control">), DataAnnotations özniteliklerini kullanır ve istemci tarafında jQuery Doğrulaması için gereken HTML özniteliklerini üretir.

gibi <form method="post">Etiket Yardımcıları hakkında daha fazla bilgi için bkz . ASP.NET Core'da Etiket Yardımcıları.

Sonraki adımlar

Oluştur, Sil, Ayrıntılar ve Düzenle sayfaları

Pages/Movies/Index.cshtml.cs Sayfa Modelini İnceleme:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get;set; } = default!;

        public async Task OnGetAsync()
        {
            if (_context.Movie != null)
            {
                Movie = await _context.Movie.ToListAsync();
            }
        }
    }
}

Razor Sayfalar' dan PageModeltüretilir. Kurala PageModel göre, türetilmiş sınıf olarak adlandırılır PageNameModel. Örneğin, Dizin sayfası olarak adlandırılır IndexModel.

Oluşturucu, öğesini sayfaya eklemek RazorPagesMovieContext için bağımlılık ekleme işlemini kullanır:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Entity Framework ile zaman uyumsuz programlama hakkında daha fazla bilgi için bkz . Zaman uyumsuz kod .

Sayfa için istekte bulunulduğunda, OnGetAsync yöntemi Sayfaya Razor bir film listesi döndürür. Bir Razor Sayfada OnGetAsync veya OnGet sayfanın durumunu başlatmak için çağrılır. Bu durumda, OnGetAsync filmlerin bir listesini alır ve görüntüler.

döndürdüğünde OnGetvoid veya OnGetAsync döndürdüğünde Task, return deyimi kullanılmaz. Örneğin, Sayfayı Privacy inceleyin:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesMovie.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

dönüş türü veya Task<IActionResult>olduğundaIActionResult, bir return deyimi sağlanmalıdır. Örneğin, Pages/Movies/Create.cshtml.csOnPostAsync yöntemi:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid || _context.Movie == null || Movie == null)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Sayfayı Pages/Movies/Index.cshtmlRazor inceleyin:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor HTML'den C# veya özel işaretlemeye Razorgeçiş yapabilir. Bir @ simgenin ardından ayrılmış anahtar Razor sözcük geçtiğinde, özel işaretlemeye Razor, aksi takdirde C# işaretine geçirilir.

yönergesi @page

yönergesi @pageRazor , dosyayı MVC eylemi yapar ve bu da istekleri işleyebileceği anlamına gelir. @page, sayfadaki ilk Razor yönergesi olmalıdır. @page ve @model özel işaretlemeye geçiş Razorörnekleridir. Daha fazla bilgi için söz dizimine bakınRazor.

yönergesi @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

yönergesi @model , Sayfaya geçirilen modelin Razor türünü belirtir. Yukarıdaki örnekte, @model satır türetilmiş sınıfı Sayfa için Razor kullanılabilir hale getirirPageModel. Model, sayfadaki ve @Html.DisplayForHTML Yardımcıları'nda @Html.DisplayNameFor kullanılır.

Aşağıdaki HTML Yardımcısı'nda kullanılan lambda ifadesini inceleyin:

@Html.DisplayNameFor(model => model.Movie[0].Title)

HTML Yardımcısı, DisplayNameFor görünen adı belirlemek için lambda ifadesinde başvuruda bulunan özelliği inceler Title . Lambda ifadesi değerlendirilmek yerine incelenir. Bu, , model.Movieveya olduğunda veya nullmodel.Movie[0] boş olduğunda modelerişim ihlali olmadığı anlamına gelir. Lambda ifadesi, örneğin ile @Html.DisplayFor(modelItem => item.Title)değerlendirildiğinde modelin özellik değerleri değerlendirilir.

Düzen sayfası

PagesMovie, Homeve Privacymenü bağlantılarını Razorseçin. Her sayfada aynı menü düzeni gösterilir. Menü düzeni dosyasında uygulanır Pages/Shared/_Layout.cshtml .

Dosyasını açın ve inceleyin Pages/Shared/_Layout.cshtml .

Düzen şablonları, HTML kapsayıcı düzeninin şu şekilde olmasını sağlar:

  • Tek bir yerde belirtilir.
  • Sitedeki birden çok sayfaya uygulanır.

@RenderBody() Satırı bulun. RenderBody , sayfaya özgü tüm görünümlerin düzen sayfasında sarmalandığı bir yer tutucudur. Örneğin, bağlantıyı Pages/Privacy.cshtml seçtiğinizde Privacy görünüm yöntemi içinde RenderBody işlenir.

ViewData ve düzen

Dosyadan aşağıdaki işaretlemeyi Pages/Movies/Index.cshtml göz önünde bulundurun:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Yukarıdaki vurgulanmış işaretleme, C# içine geçiş örneğidir Razor . { ve } karakterleri bir C# kodu bloğunu içine alır.

PageModel Temel sınıf, bir ViewData Görünüme veri geçirmek için kullanılabilecek bir sözlük özelliği içerir. Nesneler anahtar değeri deseni ViewData kullanılarak sözlüğe eklenir. Yukarıdaki örnekte özelliği Title sözlüğe eklenir ViewData .

Title özelliği dosyasında kullanılırPages/Shared/_Layout.cshtml. Aşağıdaki işaretlemede dosyanın ilk birkaç satırı gösterilmektedir _Layout.cshtml .

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>

     @*Markup removed for brevity.*@
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />

Satır @*Markup removed for brevity.*@ bir Razor açıklamadır. HTML açıklamalarının <!-- -->aksine, Razor açıklamalar istemciye gönderilmez. Daha fazla bilgi için bkz . MDN web belgeleri: HTML kullanmaya başlama.

Düzeni güncelleştirme

  1. <title> Dosyadaki Pages/Shared/_Layout.cshtml öğesini PagesMovie yerineRazor Movie görüntüleyecek şekilde değiştirin.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. Dosyasında aşağıdaki tutturucu öğesini Pages/Shared/_Layout.cshtml bulun.

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Önceki öğeyi aşağıdaki işaretlemeyle değiştirin:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Yukarıdaki yer işareti öğesi bir Etiket Yardımcısı'dır. Bu durumda, Tutturucu Etiketi Yardımcısı'dır. asp-page="/Movies/Index" Etiket Yardımcısı özniteliği ve değeri Sayfaya /Movies/IndexRazor bir bağlantı oluşturur. asp-area Öznitelik değeri boş olduğundan, alan bağlantıda kullanılmaz. Daha fazla bilgi için bkz . Alanlar .

  4. Değişiklikleri kaydedin ve RpMovie bağlantısını seçerek uygulamayı test edin. Herhangi bir sorun yaşıyorsanız GitHub'daki _Layout.cshtml dosyasına bakın.

  5. Home, RpMovie, Oluştur, Düzenle ve Sil bağlantılarını test edin. Her sayfa, tarayıcı sekmesinde görebileceğiniz başlığı ayarlar. Sayfaya yer işareti eklediğinizde, başlık yer işareti için kullanılır.

Not

Alana ondalık virgül Price giremeyebilirsiniz. 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 uygulamayı genelleştirmek için adımlar uygulamanız gerekir. Ondalık virgül ekleme yönergeleri için bu GitHub sorunu 4076'ya bakın.

Layout özelliği dosyasında ayarlanırPages/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Yukarıdaki işaretleme, Sayfalar klasörünün altındaki tüm Razor dosyalar için düzen dosyasını Pages/Shared/_Layout.cshtml olarak ayarlar. Daha fazla bilgi için bkz . Düzen .

Sayfa oluştur modeli

Pages/Movies/Create.cshtml.cs Sayfa modelini inceleyin:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; } = default!;
        

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
          if (!ModelState.IsValid || _context.Movie == null || Movie == null)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

yöntemi, OnGet sayfa için gereken tüm durumları başlatır. Oluştur sayfasının başlatacak Page bir durumu olmadığından döndürülür. Öğreticinin ilerleyen bölümlerinde durumu başlatma örneği OnGet gösterilir. yöntemi, Page sayfayı Create.cshtml işleyen bir PageResult nesne oluşturur.

özelliği, Movie model bağlamayı kabul etmek için [BindProperty] özniteliğini kullanır. Oluştur formu form değerlerini gönderdiğinde, ASP.NET Core çalışma zamanı deftere nakledilen değerleri modele Movie bağlar.

Yöntemi OnPostAsync , sayfa form verilerini gönderirken çalıştırılır:

public async Task<IActionResult> OnPostAsync()
{
  if (!ModelState.IsValid || _context.Movie == null || Movie == null)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Herhangi bir model hatası varsa form, gönderilen form verileriyle birlikte yeniden dağıtılır. Çoğu model hatası, form gönderilmeden önce istemci tarafında yakalanabilir. Model hatasına örnek olarak tarih alanı için tarihe dönüştürülemeyen bir değer gönderilebilir. İstemci tarafı doğrulama ve model doğrulaması öğreticinin ilerleyen bölümlerinde ele alınmalıdır.

Model hatası yoksa:

  • Veriler kaydedilir.
  • Tarayıcı Dizin sayfasına yönlendirilir.

Oluştur Razor Sayfası

Pages/Movies/Create.cshtmlRazor Sayfa dosyasını inceleyin:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio, Etiket Yardımcıları için kullanılan ayırt edici bir kalın yazı tipinde aşağıdaki etiketleri görüntüler:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <label asp-for="Movie.Title" class="control-label"></label>
  • <input asp-for="Movie.Title" class="form-control" />
  • <span asp-validation-for="Movie.Title" class="text-danger"></span>

Create.cshtml sayfasının VS17 görünümü

<form method="post"> öğesi bir Form Etiketi Yardımcısı'dır. Form Etiketi Yardımcısı otomatik olarak bir kötü amaçlı yazılımdan koruma belirteci içerir.

yapı iskelesi altyapısı, modeldeki her alan için kimlik dışında aşağıdakine benzer bir işaretleme oluşturur Razor :

<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
    <label asp-for="Movie.Title" class="control-label"></label>
    <input asp-for="Movie.Title" class="form-control" />
    <span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>

Doğrulama Etiketi Yardımcıları (<div asp-validation-summary ve <span asp-validation-for) doğrulama hatalarını görüntüler. Doğrulama, bu serinin ilerleyen bölümlerinde daha ayrıntılı olarak ele alınmıştır.

Etiket Etiketi Yardımcısı (<label asp-for="Movie.Title" class="control-label"></label>), özelliği için etiket başlık ve [for] özniteliğini Title oluşturur.

Giriş Etiketi Yardımcısı (<input asp-for="Movie.Title" class="form-control">), DataAnnotations özniteliklerini kullanır ve istemci tarafında jQuery Doğrulaması için gereken HTML özniteliklerini üretir.

gibi <form method="post">Etiket Yardımcıları hakkında daha fazla bilgi için bkz . ASP.NET Core'da Etiket Yardımcıları.

Sonraki adımlar

Oluştur, Sil, Ayrıntılar ve Düzenle sayfaları

Pages/Movies/Index.cshtml.cs Sayfa Modelini İnceleme:

// Unused usings removed.
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }
        public IList<Movie> Movie { get;set; }

        public async Task OnGetAsync()
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}

Razor Sayfalar' dan PageModeltüretilir. Kural gereği PageModel, -derived sınıfı olarak adlandırılır <PageName>Model. Oluşturucu, öğesini sayfaya eklemek RazorPagesMovieContext için bağımlılık ekleme işlemini kullanır:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

Entity Framework ile zaman uyumsuz programlama hakkında daha fazla bilgi için bkz . Zaman uyumsuz kod .

Sayfa için istekte bulunulduğunda, OnGetAsync yöntemi Sayfaya Razor bir film listesi döndürür. Bir Razor Sayfada OnGetAsync veya OnGet sayfanın durumunu başlatmak için çağrılır. Bu durumda, OnGetAsync filmlerin bir listesini alır ve görüntüler.

döndürdüğünde OnGetvoid veya OnGetAsync döndürdüğünde Task, return deyimi kullanılmaz. Örneğin, Privacy Sayfa:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
    }
}

dönüş türü veya Task<IActionResult>olduğundaIActionResult, bir return deyimi sağlanmalıdır. Örneğin, Pages/Movies/Create.cshtml.csOnPostAsync yöntemi:

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        _context.Movie.Add(Movie);
        await _context.SaveChangesAsync();

        return RedirectToPage("./Index");
    }
}

Sayfayı Pages/Movies/Index.cshtmlRazor inceleyin:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor HTML'den C# veya özel işaretlemeye Razorgeçiş yapabilir. Bir @ simgenin ardından ayrılmış anahtar Razor sözcük geçtiğinde, özel işaretlemeye Razor, aksi takdirde C# işaretine geçirilir.

yönergesi @page

yönergesi @pageRazor , dosyayı MVC eylemi yapar ve bu da istekleri işleyebileceği anlamına gelir. @page, sayfadaki ilk Razor yönergesi olmalıdır. @page ve @model özel işaretlemeye geçiş Razorörnekleridir. Daha fazla bilgi için söz dizimine bakınRazor.

yönergesi @model

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

yönergesi @model , Sayfaya geçirilen modelin Razor türünü belirtir. Yukarıdaki örnekte, @model çizgi türetilmiş sınıfı Sayfa için Razor kullanılabilir hale getirirPageModel. Model, sayfadaki ve @Html.DisplayForHTML Yardımcıları'nda @Html.DisplayNameFor kullanılır.

Aşağıdaki HTML Yardımcısı'nda kullanılan lambda ifadesini inceleyin:

@Html.DisplayNameFor(model => model.Movie[0].Title)

HTML Yardımcısı, DisplayNameFor görünen adı belirlemek için lambda ifadesinde başvuruda bulunan özelliği inceler Title . Lambda ifadesi değerlendirilmek yerine incelenir. Bu, , model.Movieveya olduğunda veya nullmodel.Movie[0] boş olduğunda modelerişim ihlali olmadığı anlamına gelir. Lambda ifadesi, örneğin ile @Html.DisplayFor(modelItem => item.Title)değerlendirildiğinde modelin özellik değerleri değerlendirilir.

Düzen sayfası

PagesMovie, Homeve Privacymenü bağlantılarını Razorseçin. Her sayfada aynı menü düzeni gösterilir. Menü düzeni dosyasında uygulanır Pages/Shared/_Layout.cshtml .

Dosyasını açın ve inceleyin Pages/Shared/_Layout.cshtml .

Düzen şablonları, HTML kapsayıcı düzeninin şu şekilde olmasını sağlar:

  • Tek bir yerde belirtilir.
  • Sitedeki birden çok sayfaya uygulanır.

@RenderBody() Satırı bulun. RenderBody , sayfaya özgü tüm görünümlerin düzen sayfasında sarmalandığı bir yer tutucudur. Örneğin, bağlantıyı Pages/Privacy.cshtml seçtiğinizde Privacy görünüm yöntemi içinde RenderBody işlenir.

ViewData ve düzen

Dosyadan aşağıdaki işaretlemeyi Pages/Movies/Index.cshtml göz önünde bulundurun:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Yukarıdaki vurgulanmış işaretleme, C# içine geçiş örneğidir Razor . { ve } karakterleri bir C# kodu bloğunu içine alır.

PageModel Temel sınıf, bir ViewData Görünüme veri geçirmek için kullanılabilecek bir sözlük özelliği içerir. Nesneler anahtar değeri deseni ViewData kullanılarak sözlüğe eklenir. Yukarıdaki örnekte özelliği Title sözlüğe eklenir ViewData .

Title özelliği dosyasında kullanılırPages/Shared/_Layout.cshtml. Aşağıdaki işaretlemede dosyanın ilk birkaç satırı gösterilmektedir _Layout.cshtml .

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>

    @*Markup removed for brevity.*@

Satır @*Markup removed for brevity.*@ bir Razor açıklamadır. HTML açıklamalarının <!-- -->aksine, Razor açıklamalar istemciye gönderilmez. Daha fazla bilgi için bkz . MDN web belgeleri: HTML kullanmaya başlama.

Düzeni güncelleştirme

  1. <title> Dosyadaki Pages/Shared/_Layout.cshtml öğesini PagesMovie yerineRazor Movie görüntüleyecek şekilde değiştirin.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Movie</title>
    
  2. Dosyasında aşağıdaki tutturucu öğesini Pages/Shared/_Layout.cshtml bulun.

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. Önceki öğeyi aşağıdaki işaretlemeyle değiştirin:

    <a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
    

    Yukarıdaki yer işareti öğesi bir Etiket Yardımcısı'dır. Bu durumda, Tutturucu Etiketi Yardımcısı'dır. asp-page="/Movies/Index" Etiket Yardımcısı özniteliği ve değeri Sayfaya /Movies/IndexRazor bir bağlantı oluşturur. asp-area Öznitelik değeri boş olduğundan, alan bağlantıda kullanılmaz. Daha fazla bilgi için bkz . Alanlar .

  4. Değişiklikleri kaydedin ve RpMovie bağlantısını seçerek uygulamayı test edin. Herhangi bir sorun yaşıyorsanız GitHub'daki _Layout.cshtml dosyasına bakın.

  5. Home, RpMovie, Oluştur, Düzenle ve Sil bağlantılarını test edin. Her sayfa, tarayıcı sekmesinde görebileceğiniz başlığı ayarlar. Sayfaya yer işareti eklediğinizde, başlık yer işareti için kullanılır.

Not

Alana ondalık virgül Price giremeyebilirsiniz. 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 uygulamayı genelleştirmek için adımlar uygulamanız gerekir. Ondalık virgül ekleme yönergeleri için bu GitHub sorunu 4076'ya bakın.

Layout özelliği dosyasında ayarlanırPages/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Yukarıdaki işaretleme, Sayfalar klasörünün altındaki tüm Razor dosyalar için düzen dosyasını Pages/Shared/_Layout.cshtml olarak ayarlar. Daha fazla bilgi için bkz . Düzen .

Sayfa oluştur modeli

Pages/Movies/Create.cshtml.cs Sayfa modelini inceleyin:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;
using System;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

yöntemi, OnGet sayfa için gereken tüm durumları başlatır. Oluştur sayfasının başlatacak Page bir durumu olmadığından döndürülür. Öğreticinin ilerleyen bölümlerinde durumu başlatma örneği OnGet gösterilir. yöntemi, Page sayfayı Create.cshtml işleyen bir PageResult nesne oluşturur.

özelliği, Movie model bağlamayı kabul etmek için [BindProperty] özniteliğini kullanır. Oluştur formu form değerlerini gönderdiğinde, ASP.NET Core çalışma zamanı deftere nakledilen değerleri modele Movie bağlar.

Yöntemi OnPostAsync , sayfa form verilerini gönderirken çalıştırılır:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Herhangi bir model hatası varsa form, gönderilen form verileriyle birlikte yeniden dağıtılır. Çoğu model hatası, form gönderilmeden önce istemci tarafında yakalanabilir. Model hatasına örnek olarak tarih alanı için tarihe dönüştürülemeyen bir değer gönderilebilir. İstemci tarafı doğrulama ve model doğrulaması öğreticinin ilerleyen bölümlerinde ele alınmalıdır.

Model hatası yoksa:

  • Veriler kaydedilir.
  • Tarayıcı Dizin sayfasına yönlendirilir.

Oluştur Razor Sayfası

Pages/Movies/Create.cshtmlRazor Sayfa dosyasını inceleyin:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Visual Studio, Etiket Yardımcıları için kullanılan ayırt edici bir kalın yazı tipinde aşağıdaki etiketleri görüntüler:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <label asp-for="Movie.Title" class="control-label"></label>
  • <input asp-for="Movie.Title" class="form-control" />
  • <span asp-validation-for="Movie.Title" class="text-danger"></span>

Create.cshtml sayfasının VS17 görünümü

<form method="post"> öğesi bir Form Etiketi Yardımcısı'dır. Form Etiketi Yardımcısı otomatik olarak bir kötü amaçlı yazılımdan koruma belirteci içerir.

yapı iskelesi altyapısı, modeldeki her alan için kimlik dışında aşağıdakine benzer bir işaretleme oluşturur Razor :

<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
    <label asp-for="Movie.Title" class="control-label"></label>
    <input asp-for="Movie.Title" class="form-control" />
    <span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>

Doğrulama Etiketi Yardımcıları (<div asp-validation-summary ve <span asp-validation-for) doğrulama hatalarını görüntüler. Doğrulama, bu serinin ilerleyen bölümlerinde daha ayrıntılı olarak ele alınmıştır.

Etiket Etiketi Yardımcısı (<label asp-for="Movie.Title" class="control-label"></label>), özelliği için etiket başlık ve [for] özniteliğini Title oluşturur.

Giriş Etiketi Yardımcısı (<input asp-for="Movie.Title" class="form-control">), DataAnnotations özniteliklerini kullanır ve istemci tarafında jQuery Doğrulaması için gereken HTML özniteliklerini üretir.

gibi <form method="post">Etiket Yardımcıları hakkında daha fazla bilgi için bkz . ASP.NET Core'da Etiket Yardımcıları.

Sonraki adımlar