第3部分: Razor ASP.NET Core 中的 scaffold 頁面

作者:Rick Anderson

本教學課程會檢查 Razor 先前教學課程中的樣板所建立的頁面。

Create、Delete、Details 和 Edit 頁面

檢查 Pages/電影/ Index cshtml. c 頁面模型:

// 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 頁面衍生自 PageModel 。 依照慣例, PageModel 衍生的類別會命名為 <PageName>Model 。 此函式會使用相依性 插入 將加入 RazorPagesMovieContext 至頁面:

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

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

如需使用 Entity Framework 進行非同步程式設計的詳細資訊,請參閱非同步程式碼

當對頁面提出要求時,方法會將 OnGetAsync 電影清單傳回 Razor 頁面。 在 Razor 頁面上, OnGetAsyncOnGet 被呼叫來初始化頁面的狀態。 在此情況下,OnGetAsync 會取得電影清單並加以顯示。

當傳回或傳回時 OnGet void OnGetAsync Task ,不會使用 return 語句。 例如, Privacy 頁面:

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

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

    public void OnGet()
    {
    }
}

當傳回型別是 IActionResultTask<IActionResult> 時,必須提供傳回陳述式。 例如,Pages/Movies/Create.cshtml.cs OnPostAsync 方法:

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

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

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

檢查 Pages/電影/ Index cshtml Razor 頁面:

@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 轉換成 c # 或 Razor 特定標記。 當 @ 符號後面接著 Razor 保留關鍵字時,它會轉換為 Razor 特定標記,否則會轉換成 HTML。

@page 指示詞

指示詞 @page Razor 會讓檔案成為 MVC 動作,這表示它可以處理要求。 @page 必須是頁面上的第一個指示詞 Razor 。 @page@model 是轉換為 Razor 特定標記的範例。 如需詳細資訊,請參閱 Razor 語法

@model 指示詞

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

指示詞會 @model 指定傳遞至頁面的模型類型 Razor 。 在上述範例中,這 @model 一行讓 PageModel 衍生的類別可供頁面使用 Razor 。 此模型用於頁面上的 @Html.DisplayNameFor@Html.DisplayFor HTML 協助程式

檢查下列 HTML 協助程式中使用的 Lambda 運算式:

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

DisplayNameExtensions.DisplayNameFor HTML 協助程式會檢查 Lambda 運算式中參考的 Title 屬性來判斷顯示名稱。 Lambda 運算式是進行檢查而不是評估。 這表示當 modelmodel.Moviemodel.Movie[0]null 或空白時,不會發生存取違規。 例如,在評估 lambda 運算式時(例如), @Html.DisplayFor(modelItem => item.Title) 會評估模型的屬性值。

版面配置頁

選取功能表連結 Razor PagesMovieHomePrivacy 。 每個頁面會顯示相同的功能表配置。 功能表配置會在 Pages/Shared/_Layout.cshtml 檔案中實作。

開啟並檢查 Pages/Shared/_Layout 的 cshtml 檔案。

版面配置範本可讓 HTML 容器版面配置:

  • 指定在一個位置。
  • 套用於網站中的多個頁面。

找到 @RenderBody() 這行。 RenderBody 是一個預留位置,可供顯示所有頁面特定檢視 (「包裝」在版面配置頁面中)。 例如,選取 Privacy 連結,然後在方法內轉譯 Pages/ Privacy . cshtml view RenderBody

ViewData 和 Layout

請考慮下列 Pages/電影/ Index cshtml 檔案的標記:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

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

上述反白顯示的標記是 Razor 轉換成 c # 的範例。 {} 字元中含括 C# 程式碼的區塊。

PageModel基類包含 ViewData 字典屬性,可用來將資料傳遞給視圖。 ViewData使用索引 鍵值 模式,將物件新增至字典。 在上述範例中,Title 屬性會新增至 ViewData 字典。

Pages/Shared/_Layout.cshtml 檔案中使用 Title 屬性。 下列標記會顯示 _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.*@

這一行 @*Markup removed for brevity.*@ 是 Razor 批註。 與 HTML 批註不同的 <!-- --> Razor 是,不會將批註傳送給用戶端。 如需詳細資訊,請參閱 MDN web 檔:開始使用 HTML

更新配置

  1. 變更 <title> Pages/Shared/_Layout cshtml 檔案中的專案,以顯示 電影,而不是 Razor PagesMovie

    <!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. Pages/Shared/_Layout.cshtml 檔案中尋找下列錨點元素。

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. 以下列標記來取代上述元素:

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

    上述的錨點項目是標記協助程式。 在此情況下,它是錨點標記協助程式。 標籤協助程式 asp-page="/Movies/Index" 屬性和值會建立頁面的連結 /Movies/Index Razor 。 asp-area 屬性值為空白,因此不會在連結中使用該區域。 如需詳細資訊,請參閱區域

  4. 儲存變更,然後選取 [ >rpmovie ] 連結來測試應用程式。 如有任何問題,請參閱 GitHub 中的 _Layout.cshtml 檔案。

  5. 測試 Home>rpmovie建立編輯刪除 連結。 每個頁面都會設定標題,您可以在 [瀏覽器] 索引標籤中看到此標題。當您將頁面加入書簽時,此標題會用於書簽。

注意

您可能無法在 Price 欄位中輸入小數逗號。 若要針對使用逗號 ( "," ) 作為小數點的非英文地區設定和非 US-English 日期格式支援 jQuery 驗證 ,您必須採取步驟來全球化應用程式。 請參閱此 GitHub 問題 4076 (英文),以取得加入十進位逗號的指示。

Layout 屬性是在 Pages/_ViewStart.cshtml 檔案中設定:

@{
    Layout = "_Layout";
}

上述標記會將 Pages 資料夾下的所有檔案的版面配置檔案設定為 pages/Shared/_Layout。 Razor 如需詳細資訊,請參閱 Layout

Create 頁面模型

檢查 Pages/Movies/Create.cshtml.cs 頁面模型:

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

OnGet 方法會初始化頁面所需的任何狀態。 建立頁面沒有任何要初始化的狀態,所以傳回 Page。 稍後在此教學課程中,會顯示 OnGet 初始化狀態的範例。 Page 方法會建立 PageResult 物件,用以呈現 Create.cshtml 頁面。

Movie屬性使用[BindProperty]屬性加入模型系結。 當 Create 表單發佈表單值時,ASP.NET Core 執行階段會將發佈的值繫結至 Movie 模型。

當頁面發佈表單資料時,即會執行 OnPostAsync 方法:

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

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

    return RedirectToPage("./Index");
}

如果沒有任何模型錯誤,將會重新顯示表單,以及任何發佈的表單資料。 大部分的模型錯誤可以在發佈表單之前,於用戶端上攔截到。 模型錯誤的範例為針對日期欄位發佈無法轉換為日期的值。 稍後的教學課程中將討論用戶端驗證和模型驗證。

如果沒有任何模型錯誤:

  • 儲存資料。
  • 瀏覽器會重新導向至該 Index 頁面。

[建立] Razor 頁面

檢查 Pages/電影/Create. cshtml Razor 分頁檔案:

@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 會以用於標籤協助程式的特殊粗體字型顯示下列標籤:

  • <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 頁面的 VS17 檢視

<form method="post"> 項目是表單標記協助程式。 表單標記協助程式會自動包含 antiforgery 語彙基元

此範例引擎會 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>

驗證標籤協助程式 (<div asp-validation-summary ,並 <span asp-validation-for) 顯示驗證錯誤。 驗證將於本文稍後詳細討論到。

標籤標記協助 <label asp-for="Movie.Title" class="control-label"></label> 程式 () 會產生屬性的標籤標題和 [for] 屬性 Title

輸入標記協助程式 (<input asp-for="Movie.Title" class="form-control">) 會使用DataAnnotations屬性,並產生在用戶端上進行 JQUERY 驗證所需的 HTML 屬性。

如需標籤協助程式 (例如 <form method="post">) 的詳細資訊,請參閱 ASP.NET Core 中的標籤協助程式

其他資源

Create、Delete、Details 和 Edit 頁面

檢查 Pages/電影/ Index cshtml. c 頁面模型:

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

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

Razor 頁面衍生自 PageModel 。 依照慣例, PageModel 衍生的類別會命名為 PageNameModel 。 例如,頁面的 Index 名稱為 IndexModel

此函式會使用相依性 插入 將加入 RazorPagesMovieContext 至頁面:

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

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

如需使用 Entity Framework 進行非同步程式設計的詳細資訊,請參閱非同步程式碼

當對頁面提出要求時,方法會將 OnGetAsync 電影清單傳回 Razor 頁面。 在 Razor 頁面上, OnGetAsyncOnGet 被呼叫來初始化頁面的狀態。 在此情況下,OnGetAsync 會取得電影清單並加以顯示。

當傳回或傳回時 OnGet void OnGetAsync Task ,不會使用 return 語句。 例如,檢查 Privacy 頁面:

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()
    {
    }
}

當傳回型別是 IActionResultTask<IActionResult> 時,必須提供傳回陳述式。 例如,Pages/Movies/Create.cshtml.cs OnPostAsync 方法:

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

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

    return RedirectToPage("./Index");
}

檢查 Pages/電影/ Index cshtml Razor 頁面:

@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 轉換成 c # 或 Razor 特定標記。 當 @ 符號後面接著 Razor 保留關鍵字時,它會轉換為 Razor 特定標記,否則會轉換成 c #。

@page 指示詞

指示詞 @page Razor 會讓檔案成為 MVC 動作,這表示它可以處理要求。 @page 必須是頁面上的第一個指示詞 Razor 。 @page@model 是轉換為 Razor 特定標記的範例。 如需詳細資訊,請參閱 Razor 語法

@model 指示詞

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

指示詞會 @model 指定傳遞至頁面的模型類型 Razor 。 在上述範例中,這 @model 一行讓 PageModel 衍生類別可供頁面使用 Razor 。 此模型用於頁面上的 @Html.DisplayNameFor@Html.DisplayFor HTML 協助程式

檢查下列 HTML 協助程式中使用的 Lambda 運算式:

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

DisplayNameExtensions.DisplayNameFor HTML 協助程式會檢查 Lambda 運算式中參考的 Title 屬性來判斷顯示名稱。 Lambda 運算式是進行檢查而不是評估。 這表示當 modelmodel.Moviemodel.Movie[0]null 或空白時,不會發生存取違規。 例如,在評估 lambda 運算式時(例如), @Html.DisplayFor(modelItem => item.Title) 會評估模型的屬性值。

版面配置頁

選取功能表連結 Razor PagesMovieHomePrivacy 。 每個頁面會顯示相同的功能表配置。 功能表配置會在 Pages/Shared/_Layout.cshtml 檔案中實作。

開啟並檢查 Pages/Shared/_Layout 的 cshtml 檔案。

版面配置範本可讓 HTML 容器版面配置:

  • 指定在一個位置。
  • 套用於網站中的多個頁面。

找到 @RenderBody() 這行。 RenderBody 是一個預留位置,可供顯示所有頁面特定檢視 (「包裝」在版面配置頁面中)。 例如,選取 Privacy 連結,然後在方法內轉譯 Pages/ Privacy . cshtml view RenderBody

ViewData 和 Layout

請考慮下列 Pages/電影/ Index cshtml 檔案的標記:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

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

上述反白顯示的標記是 Razor 轉換成 c # 的範例。 {} 字元中含括 C# 程式碼的區塊。

PageModel基類包含 ViewData 字典屬性,可用來將資料傳遞給視圖。 ViewData使用索引 鍵值 模式,將物件新增至字典。 在上述範例中,Title 屬性會新增至 ViewData 字典。

Pages/Shared/_Layout.cshtml 檔案中使用 Title 屬性。 下列標記會顯示 _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"] - Movie</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />

這一行 @*Markup removed for brevity.*@ 是 Razor 批註。 與 HTML 批註不同的 <!-- --> Razor 是,不會將批註傳送給用戶端。 如需詳細資訊,請參閱 MDN web 檔:開始使用 HTML

更新配置

  1. 變更 <title> Pages/Shared/_Layout cshtml 檔案中的專案,以顯示 電影,而不是 Razor PagesMovie

    <!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. Pages/Shared/_Layout.cshtml 檔案中尋找下列錨點元素。

    <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
    
  3. 以下列標記來取代上述元素:

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

    上述的錨點項目是標記協助程式。 在此情況下,它是錨點標記協助程式。 標籤協助程式 asp-page="/Movies/Index" 屬性和值會建立頁面的連結 /Movies/Index Razor 。 asp-area 屬性值為空白,因此不會在連結中使用該區域。 如需詳細資訊,請參閱區域

  4. 儲存變更,然後選取 [ >rpmovie ] 連結來測試應用程式。 如有任何問題,請參閱 GitHub 中的 _Layout.cshtml 檔案。

  5. 測試 Home>rpmovie建立編輯刪除 連結。 每個頁面都會設定標題,您可以在 [瀏覽器] 索引標籤中看到此標題。當您將頁面加入書簽時,此標題會用於書簽。

注意

您可能無法在 Price 欄位中輸入小數逗號。 若要針對使用逗號 ( "," ) 作為小數點的非英文地區設定和非 US-English 日期格式支援 jQuery 驗證 ,您必須採取步驟來全球化應用程式。 請參閱此 GitHub 問題 4076 (英文),以取得加入十進位逗號的指示。

Layout 屬性是在 Pages/_ViewStart.cshtml 檔案中設定:

@{
    Layout = "_Layout";
}

上述標記會將 Pages 資料夾下的所有檔案的版面配置檔案設定為 pages/Shared/_Layout。 Razor 如需詳細資訊,請參閱 Layout

Create 頁面模型

檢查 Pages/Movies/Create.cshtml.cs 頁面模型:

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

namespace RazorPagesMovie.Pages.Movies
{
#pragma warning disable CS8618
#pragma warning disable CS8602

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

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

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

            return RedirectToPage("./Index");
        }
    }
#pragma warning restore CS8618
#pragma warning restore CS8602
}

OnGet 方法會初始化頁面所需的任何狀態。 建立頁面沒有任何要初始化的狀態,所以傳回 Page。 稍後在此教學課程中,會顯示 OnGet 初始化狀態的範例。 Page 方法會建立 PageResult 物件,用以呈現 Create.cshtml 頁面。

Movie屬性使用[BindProperty]屬性加入模型系結。 當 Create 表單發佈表單值時,ASP.NET Core 執行階段會將發佈的值繫結至 Movie 模型。

當頁面發佈表單資料時,即會執行 OnPostAsync 方法:

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

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

    return RedirectToPage("./Index");
}

如果沒有任何模型錯誤,將會重新顯示表單,以及任何發佈的表單資料。 大部分的模型錯誤可以在發佈表單之前,於用戶端上攔截到。 模型錯誤的範例為針對日期欄位發佈無法轉換為日期的值。 稍後的教學課程中將討論用戶端驗證和模型驗證。

如果沒有任何模型錯誤:

  • 儲存資料。
  • 瀏覽器會重新導向至該 Index 頁面。

[建立] Razor 頁面

檢查 Pages/電影/Create. cshtml Razor 分頁檔案:

@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 會以用於標籤協助程式的特殊粗體字型顯示下列標籤:

  • <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 頁面的 VS17 檢視

<form method="post"> 項目是表單標記協助程式。 表單標記協助程式會自動包含 antiforgery 語彙基元

此範例引擎會 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>

驗證標籤協助程式 (<div asp-validation-summary ,並 <span asp-validation-for) 顯示驗證錯誤。 驗證將於本文稍後詳細討論到。

標籤標記協助 <label asp-for="Movie.Title" class="control-label"></label> 程式 () 會產生屬性的標籤標題和 [for] 屬性 Title

輸入標記協助程式 (<input asp-for="Movie.Title" class="form-control">) 會使用DataAnnotations屬性,並產生在用戶端上進行 JQUERY 驗證所需的 HTML 屬性。

如需標籤協助程式 (例如 <form method="post">) 的詳細資訊,請參閱 ASP.NET Core 中的標籤協助程式

其他資源