2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ASP.NET Core 3.0 Razor Pages 事始め(9) - ページに新しいフィールドを追加する

Last updated at Posted at 2019-11-18

記事目次

  1. ASP.NET Core 3.0 Razor Pages 事始め(1) - はじめてのRazor Pagesアプリケーション
  2. ASP.NET Core 3.0 Razor Pages 事始め(2) - スキャフォールディングとDBマイグレーション
  3. ASP.NET Core 3.0 Razor Pages 事始め(3) - マイグレーションのやり直しとURLルーティング
  4. ASP.NET Core 3.0 Razor Pages 事始め(4) - ページモデルとページハンドラ
  5. ASP.NET Core 3.0 Razor Pages 事始め(5) - Postページハンドラとタグヘルパー
  6. ASP.NET Core 3.0 Razor Pages 事始め(6) - データベースに初期値を設定する
  7. ASP.NET Core 3.0 Razor Pages 事始め(7) - Viewの変更とコンカレンシー例外処理
  8. ASP.NET Core 3.0 Razor Pages 事始め(8) - 検索機能の追加
  9. ASP.NET Core 3.0 Razor Pages 事始め(9) - ページに新しいフィールドを追加する <-- この記事
  10. ASP.NET Core 3.0 Razor Pages 事始め(10) - 検証機能の追加

ASP.NET Core 3.0 Razor Pages 事始め(8)の続きです。

今回は公式チュートリアルのASP.NET Core で Razor ページに新しいフィールドを追加するに沿って進めていこうと思います。

モデルへプロパティを追加

それでは、チュートリアルに沿って進めていきます。まず、Movieモデルへ評価を示すプロパティを追加します。

Models/Movie.cs ファイルを開き、Rating プロパティを追加します。

    [Display(Name = "レイティング")]
    public string Rating { get; set; }

Index.cshtmlを開き、Rating フィールドを追加します。

@page 
@model RazorPagesMovie.Pages.Movies.IndexModel

... 

<table class="table">
    <thead>
        <tr>

            ... 

            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies) {
        <tr>

            ... 

            <td>
                @Html.DisplayFor(modelItem => item.Rating)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.ID">編集</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">詳細</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">削除</a>
            </td>
        </tr>
        }
    </tbody>
</table>

Create.cshtmlにも、Ratingのフィールドを追加します。

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

同様にして、Edit.cshtml, Delete.cshtml, Details.cshtml にもRatingフィールドを追加します。

ビルドして、実行してみます。

しかし、Indexページを開こうとすると、以下の例外が発生してしまいます。

An unhandled exception occurred while processing the request.

SqliteException: SQLite Error 1: 'no such column: m.Rating'.
Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(int rc, sqlite3 db)

これは、データベースのMovie テーブにRatingカラムがまだ存在しないためです。

Code First Migrations

Code First Migrations を利用して、これを解決します。

まず、SeedDataクラスを変更し、Ratingプロパティに値を設定するようにします。

   context.Movies.AddRange(
        new Movie
        {
            Title = "When Harry Met Sally",
            ReleaseDate = DateTime.Parse("1989-2-12"),
            Genre = "Romantic Comedy",
            Price = 800M,
            Rating = "R",
        },

        new Movie
        {
            Title = "Ghostbusters ",
            ReleaseDate = DateTime.Parse("1984-3-13"),
            Genre = "Comedy",
            Price = 900M,
            Rating = "G",
        },

        new Movie
        {
            Title = "Ghostbusters 2",
            ReleaseDate = DateTime.Parse("1986-2-23"),
            Genre = "Comedy",
            Price =1000M,
            Rating = "G",
        },

        new Movie
        {
            Title = "Rio Bravo",
            ReleaseDate = DateTime.Parse("1959-4-15"),
            Genre = "Western",
            Price = 500M,
            Rating = "NA",
        }
    );

次のコマンドを実行します。

dotnet ef database drop
dotnet ef migrations add addrating
dotnet ef database update

最初にDBを削除します。これは、SeedDataでのデータ初期化コードを動かすためです。

以下実行結果の抜粋です。

$ dotnet ef database drop
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 3.0.0 initialized 'RazorPagesMovieContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
Are you sure you want to drop the database 'main' on server 'MvcMovie.db'? (y/N)
y
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 3.0.0 initialized 'RazorPagesMovieContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
Dropping database 'main'.
Successfully dropped database 'main'.

$ dotnet ef migrations add addrating
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 3.0.0 initialized 'RazorPagesMovieContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
Done. To undo this action, use 'ef migrations remove'

$ dotnet ef database update
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 3.0.0 initialized 'RazorPagesMovieContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
info: Microsoft.EntityFrameworkCore.Database.Command[20100]
      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
      PRAGMA journal_mode = 'wal';
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
PRAGMA journal_mode = 'wal';
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "__EFMigrationsHistory" (
    "MigrationId" TEXT NOT NULL CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY,
    "ProductVersion" TEXT NOT NULL
);

…

Done.

正常に終了しました。

なお、SQLiteの場合、EFはカラムの変更はサポートしていませんでしたが、試した範囲では、
カラムの追加は大丈夫みたいです。dropでDB削除せずに、マイグレーションを行なってみましたが、正常にコマンドが終了しました。

実行してみる

それでは、実行してみます。

スクリーンショット 2019-11-15 20.43.09.png

うまく動作しました。

新規追加、編集、詳細なども動作するかを確認します。

スクリーンショット 2019-11-15 20.46.08.png

ところで、この "R"ってなんだろう? 調べたら、Restricted の頭文字のようです。

R:17歳未満の子供は同伴する保護者または成人の保護者が必要です。

ということらしいです。G, PG, PG-13, R, NC-17 があるらしいです。

サンプルコードで代入されていた NAは、評価無しということかな。

入力時も小数点以下を表示しないようにする

ここまで書いて気がついたんですが、

 [DisplayFormat(DataFormatString ="{0:#,0}")]
 public decimal Price { get; set; }

と指定してるのに、編集ページ(Edit.cshtml)では、

スクリーンショット 2019-11-15 20.59.08.png

小数部が表示されてます。この小数部を表示しないようにするには、ApplyFormatInEditModeプロパティを使えば良いみたいです。

 [DisplayFormat(DataFormatString ="{0:#,0}", ApplyFormatInEditMode = true)]
 public decimal Price { get; set; }

これで以下のような表示になりました。

スクリーンショット 2019-11-15 20.55.28.png


今回はこれでおしまい。いよいよ次回がチュートリアルの最後となります。

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?