情報応用演習Ⅰ(2024)

【課題6-03】商品管理その1(新規作成・一覧表示のみ)

プロジェクトタイプASP.NET Core Web アプリ(Model-View-Controller)
プロジェクト名Prac_6_03
ソリューション名PIT6x
ターゲットフレームワーク.NET 8.0(長期的なサポート)
最上位レベルのステートメントを使用しない使用する(チェックオフ)
今回の課題について
  • 作業成果物とは別のソリューションとなるので注意すること!!
    • 作業成果物とはソリューション名が異なる.
      • 作業成果物→PIT6
      • プログラミング課題→PIT6x
  • 今回の課題はWebClassに提出場所があるのでそちらに提出すること.
    • 今までの課題と異なり今回の課題はリアクションペーパーに記載するものではないことに注意せよ.
  • これらはすべて課題点として成績に算入される課題である.
    • 加点要素ではなく 必須の課題である ことに注意せよ.

とある商店で扱う個々の商品の情報を新規作成・一覧表示ができるWeb アプリケーションを作成せよ. コントローラー名やアクション名などは_に従うこと. また,画面の挙動については_をよく見て実装すること

画面イメージと画面遷移
注意
  • この設問ではコントローラーは基本的に手作業で作成すること.
    • Homeを除いてVisual Studio の機能を用いて自動生成したコントローラーを使用しないこと.
  • やりかたによらず 自分以外(他の学生,学外の協力者,生成AIなど)が作成したソースコードを自身の成果物として提出してはならない
    • 違反が発覚した場合,その課題の評点と同じだけ成績から引くこととする.他の学生と回答を共有した場合は,元がどちらであるかに関わらず両者とも同じ処分とする. 課題は独力で取り組みむこと

このアプリはHomeコントローラーと,Productsコントローラーの二つのコントローラーで構成される.

Homeコントローラーの各アクションの処理内容を_に示す.

Homeコントローラーのアクション
アクションGET メソッドでアクセスした際の機能POST メソッドでアクセスした際の機能
Index入口ページの表示

備考 : -
(POSTでのアクセスはしない)
AccessErrorアクセスエラーの表示

備考 : -
-

メインの処理はProductsコントローラーで行う. Productsコントローラーの各アクションの処理内容を_に示す.

Productsコントローラーのアクション
アクションGET メソッドでアクセスした際の機能POST メソッドでアクセスした際の機能
Index商品一覧の表示

備考 : 「ID」の昇順で表示する.
(POSTでのアクセスはしない)
Createフォームの表示

備考 : 入力欄にはあらかじめ以下のように入力されている状態とすること.
・名前→(空欄)
・定価→0
・説明→(空欄)
DBへ新規レコードの追加

備考1 : 処理後の遷移先は以下のようになる.
入力データが正常な場合 : Indexへ遷移
入力データに誤りがある場合 : Createへ遷移
備考2 : 入力欄にはあらかじめ以下のように入力されている状態とすること.
・名前→以前に入力した値
・定価→以前に入力した値
・説明→以前に入力した値

このアプリでは_に示す「商品」の情報を表すクラスProductを作成して使用すること.

「商品」の情報
項目名プロパティ名必須/任意データ型備考
IDId必須整数-
商品名Name必須文字列その商品の名前.
定価Price必須整数その商品の低下.1以上,上限なし
説明Description任意文字列その商品の説明.

準備作業

プロジェクトを作成したら以下の準備作業を行こと

  • 【作業Ⅰ】 作業対象:プロジェクトPrac_6_03
    • 必要なパッケージをインストールする(後述).
  • 【作業Ⅱ】 作業対象:プロジェクトPrac_6_03
  • 【作業Ⅲ】 作業対象:プロジェクトPrac_6_03
    • このプロジェクトで使用するデータコンテキストクラスPrac_6_03Contextを定義する.
  • 【作業Ⅳ】 作業対象:Views/Shared/_Layout.cshtml(ファイル)
  • 【作業Ⅴ】 作業対象:wwwroot/css/site.css(ファイル)
    • 必要なスタイル指定を追記する(後述).
  • 【作業Ⅵ】 作業対象:pgAdmin(データベース)
    • 接続ユーザーの作成(参考:リスト5a-4-2)
      • このアプリでは_の設定で接続するようにする.
  • 【作業Ⅶ】 作業対象:appsettings.json(ファイル)
  • 【作業Ⅷ】 作業対象:Homeコントローラー&ビュー
    • AccessErrorアクションを作成する(参考:リスト4b-6-3).
    • ↑に対応するビューを作成する(参考:リスト4b-6-4).
    • Indexアクションのビューに追記する(後述).
  • 【作業Ⅸ】 作業対象:Program.cs(ファイル)
  • 【作業Ⅹ】 作業対象:コマンドラインターミナル1(Visual Studio 上)
    • 最初のマイグレーションの作成(マイグレーション名は"InitialDB")とデータベースへの反映(参考:リスト5a-5-1)
データベースの接続設定
項目
接続先localhost
ポート5432
ユーザー名prac_6_03_user
データベース名prac_6_03_db
パスワードeqgBhNAnHa3q
【作業Ⅰ】
【作業Ⅰ】

NuGetを使って以下のパッケージを探してプロジェクトにインストールする. バージョンが選択可能な場合は「 最新の安定板 」を選択するのを忘れないようにしよう.

パッケージソースパッケージ名本校執筆時の安定版
nuget.orgMicrosoft.EntityFrameworkCore.Design8.0.2
Npgsql.EntityFrameworkCore.PostgreSQL8.0.2
Npgsql.EntityFrameworkCore.PostgreSQL.Design1.1.0
knzw.techKnzwTech.AspNetCore.ResourceBasedLocalization.ja6.0.1
【作業Ⅰ】 : 閉じる
【作業Ⅱ】
【作業Ⅱ】

チュートリアル【T4a】チュートリアル【T5a】を参考に プロジェクトのModelsフォルダ内に新規にクラスを追加し,_の情報を含むモデルクラスProductを定義する. このクラスのテンプレートとして_を用いること.

Productクラス
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
using System.ComponentModel.DataAnnotations;

namespace Prac_6_03.Models
{
    public class Product
    {
        [Display(Name="ID")]
        public int Id { get; set; }

        /******************************/
        /*                            */
        /*            空欄            */
        /*                            */
        /******************************/
        
    }// end of class Product
}// end of namespace 
【作業Ⅱ】 : 閉じる
【作業Ⅲ】
【作業Ⅲ】

チュートリアル【T5a】を参考にこのプロジェクトで使用する データコンテキストクラスを作成する.プロジェクトにDataという名前のフォルダを追加し,その中に_に示すクラス定義を追加する.

データコンテキストクラス
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
using Microsoft.EntityFrameworkCore;
using Prac_6_03.Models;

namespace Prac_6_03.Data
{
    public class Prac_6_03Context : DbContext
    {
        public Prac_6_03Context(DbContextOptions<Prac_6_03Context> opt)
            : base(opt) 
        { }

        public DbSet<Product> Products => Set<Product>();
    }
}
【作業Ⅲ】 : 閉じる
【作業Ⅳ】
【作業Ⅳ】

チュートリアル【T4a】を参考に以下のことを行う.

  • Views/Shared/_Layout.cshtml をリスト4a-4-2に示すように変更する.
  • ↑の6行目の T4aPrac_6_03 に変更し,サイトタイトルの部分を 【課題6-03】 に変更する.
【作業Ⅳ】 : 閉じる
【作業Ⅴ】
【作業Ⅴ】

wwwroot/css/site.css の末尾に_を追記する.

wwwroot/css/site.cssの追記内容
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
body {
    padding: 1em;
}

table {
    border-collapse: collapse;
}

th, td {
    border: 1px solid black;
}

th {
    background: #404040;
    color: white;
    text-align: center;
    font-weight: bold;
}

.table th {
    color: inherit;
}
【作業Ⅴ】 : 閉じる
【作業Ⅵ】
【作業Ⅵ】

pgAdmin を起動し,「Servers」→ 「PostgreSQL 16」→ 「Databases」 に表示される データベースの一覧から 「postgres」を右クリックし「Query Tool」をクリックし,_に示すSQL文を実行する.

ユーザー作成のためのSQL文
1
2
3
CREATE ROLE "prac_6_03_user"
       WITH NOSUPERUSER LOGIN CREATEDB
   PASSWORD 'eqgBhNAnHa3q'
【作業Ⅵ】 : 閉じる
【作業Ⅶ】
【作業Ⅶ】

チュートリアル【T5a】を参考に appsettings.json に _に示す内容を追記する.

appsettings.jsonの編集結果
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "Prac_6_03Context": "Host=localhost;Port=5432;Database=wprac_6_03_db;Username=prac_6_03_user;Password=eqgBhNAnHa3q"
  }
}
【作業Ⅶ】 : 閉じる
【作業Ⅷ】
【作業Ⅷ】

チュートリアル【T4b】を参考に以下のことを行う.

  • Home コントローラーにリスト4b-6-3のアクションメソッド AccessError を追記する.
  • プロジェクト内の Views フォルダの Home フォルダに新規に AccessError (.cshtml)という名前のビューを追加し,リスト4b-6-4の内容を書き込む
  • Views/Home/Index.cshtml を_の通りに書き換える.
Views/Home/Index.cshtmlの内容
1
2
3
4
5
@{
    ViewData["Title"] = "Home Page";
}

<a asp-controller="Products" asp-action="Index">商品管理へ</a>
【作業Ⅷ】 : 閉じる
【作業Ⅸ】
【作業Ⅸ】

チュートリアル【T4a】チュートリアル【T4b】チュートリアル【T5a】チュートリアル【T5b】を参考に Program.csを編集する.正しく編集すると_のようになる.

Program.csの内容
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using KnzwTech.AspNetCore.ResourceBasedLocalization;
using Microsoft.EntityFrameworkCore;
using Prac_6_03.Data;

AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews(opt => opt.EnableDefaultErrorMessagesFromResource());
builder.Services.AddDbContext<Prac_6_03Context>(opt 
    => opt.UseNpgsql(builder.Configuration.GetConnectionString(nameof(Prac_6_03Context))));
    
var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();

app.UseStatusCodePagesWithReExecute("/Home/AccessError/{0}");

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();
【作業Ⅸ】 : 閉じる
【作業Ⅹ】
【作業Ⅹ】

Visual Studio 上でコマンドラインターミナル1を開き _に示すコマンドを実行する. このコマンドを実行する前にカレントディレクトリを,操作対象のプロジェクトのプロジェクトフォルダに変更しておく ことを忘れないようにしよう(つまりあらかじめ「cd プロジェクト名」を実行しておく).

このコマンドを実行する前に一度以上プロジェクトをビルドしておく必要がある.また,ソリューションに含まれるプロジェクトに1つでもコンパイルエラーがあるとこのコマンドは失敗することがある.このためこのコマンドを実行する際は,事前にソリューション全体を一度ビルドして一つもコンパイルエラーがないことを確認しておくこと.

マイグレーション処理の生成と実行
> dotnet ef migrations add InitialDB
> dotnet ef database update
【作業Ⅹ】 : 閉じる

各種テンプレート

いくつかのファイルに関しては以下のテンプレートを使用すること.

Views/Products/Index.cshtml

Views/Products/Index.cshtml は_を使用すること.

Views/Products/Index.cshtml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@model IEnumerable<Product>

@{
    ViewData["Title"] = "商品一覧";

    if (Model is null) throw new ArgumentNullException(nameof(Model));
}

<table>
  <tr>
    <th>@Html.DisplayNameFor(model => model.Id)</th>
    <th>@Html.DisplayNameFor(model => model.Name)</th>
    <th>@Html.DisplayNameFor(model => model.Price)</th>
    <th>@Html.DisplayNameFor(model => model.Description)</th>
  </tr>

  @foreach(var p in Model)
  {
      <tr>
        <td>@Html.DisplayFor(_ => p.Id)</td>
        <td>@Html.DisplayFor(_ => p.Name)</td>
        <td>@Html.DisplayFor(_ => p.Price)</td>
        <td>@Html.DisplayFor(_ => p.Description)</td>
      </tr>
  }
</table>

<a asp-action="Create">新規作成</a>
Views/Products/Index.cshtml : 閉じる
Views/Products/Create.cshtml

Views/Products/Create.cshtml は_を使用すること.

Views/Products/Create.cshtml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@model Product

@{
    ViewData["Title"] = "商品登録";

    if (Model is null) throw new ArgumentNullException(nameof(Model));
}

<form asp-action="Create" method="post">
    <label asp-for="@Model.Name"></label>:
    <input asp-for="@Model.Name" />
    <span asp-validation-for="@Model.Name"></span>
    <br />

    <label asp-for="@Model.Price"></label>:
    <input asp-for="@Model.Price" />
    <span asp-validation-for="@Model.Price"></span>
    <br />

    <label asp-for="@Model.Description"></label>:
    <input asp-for="@Model.Description" />
    <span asp-validation-for="@Model.Description"></span>
    <br />

    <input type="submit" value="登録" />
</form>

<a asp-action="Index">一覧へ戻る</a>

@section Scripts{
    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
Views/Products/Create.cshtml : 閉じる

実行結果

正しく実装できた場合,実行結果は_のようになる (制作の都合上,動画ではプロジェクト名などが異なるが提出物では冒頭の指定を守ること).

実行結果

ヒント

なし


  1. タブのタイトルは「開発用PowerShell」もしくは「Developer PowerShell」となっている. ↩︎ ↩︎

Last updated on 2024-06-10
Published on 2024-06-10

Powered by Hugo. Theme by TechDoc. Designed by Thingsym.