ASP.NET Core MVC で 簡単なWebアプリを作成②

ASP.NET Core MVC で 簡単なWebアプリを作成②

目次

はじめに
プロジェクトの作成
ルーティングの仕組み
モックの作成
補足:最上位レベルのステートメントを使用するとは
次回予告

はじめに

本記事は、ASP.NET Core MVC を利用したWebアプリケーション開発について、勉強用兼備忘録として執筆しています。最終的に、簡単なWebアプリ(TODOアプリ)を作成することが目標になります。

前回は、ASP.NET Core MVC の概要について簡単にご紹介いたしました。


今回は、実際に ASP.NET Core MVC でプロジェクトを作り、Webページを表示させてみようと思います。

プロジェクトの作成

では早速、Visual Studio でプロジェクトの作成を行います。
Visual Studio を起動し、「新しいプロジェクトの作成」を選択。
「ASP.NET Core Web アプリ (Model-View-Controller) 」を選択し、「次へ」をクリック。

プロジェクト名に任意の名前「MvcApplication1」を入力し、「次へ」をクリック。

「.NET 7.0」を選択し、「最上位レベルのステートメントを使用しない」にチェックをつけず「作成」をクリックします。
※最上位レベルのステートメントを使用する/しないのオプションは、.NET6 から選択できます。
 最上位レベルのステートメントを使用することで、必要とされる余分な手続きを避けることができます ※詳細はこちら

ソリューションエクスプローラーを見ると、既に沢山ファイルが作成されていることが分かります。
Visual Studio により、作成したプロジェクトに既定の MVC プロジェクト テンプレートが使用されているということですね。

今の状態で起動してみるとどう表示されるのでしょうか?「htpps」ボタンをクリックしてデバッグします。

「Welcome」の画面が表示され、ちょっとしたサイトが既にできていることが確認できました!
Webサービスを作りたい場合、ここから少し手を加えるだけで公開できそうな感じがしますね。

ルーティングの仕組み

URL等を何も設定することなく画面が表示されましたが、実際のルーティングがどのようになっているか見ていきたいと思います。
ルーティングとは、クライアントからのリクエスト URL とその URL に対応する処理を関連付けることを指し、ルーティングの処理はコントローラーで行います。
ASP.NET Core MVC には、「Program.cs」の23-25行目に以下のようなコードがあります。

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

これはURLにアクセスした時、最初に行われるコントローラのアクションを定義するものになります。コードの内容としては、 Home コントローラの Index アクションメソッドを実行するといったことが定義されています。

実際に「Controllers」フォルダ配下を確認すると、プロジェクト作成時に「HomeController.cs」が自動作成されていることが確認できます。

では、「 HomeController.cs 」の中身を確認してみます。

using Microsoft.AspNetCore.Mvc;
using MvcApplication1.Models;
using System.Diagnostics;

namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

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

        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

16~19行目を見ると、このIndex()は 、 View() を返しているだけのメソッドということが分かります。
ここでいう View() は、/Views/コントローラー名/アクションメソッド名.cshtmlに該当しますので、今回でいうと、「 Views/Home/Index.cshtml 」を参照していることになります。

では、実際に「 Views/Home/Index.cshtml 」の中身を確認してみます。

@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

メイン画面に表示されていた「Welcome」と「Learn about …」が確かに記載されていますね!

モックの作成

今回 TODOアプリを作成するにあたり、まずモックの作成を行うことにします。
画面の動きをつけず、表示するデータも固定として、簡単に「 Views/Home/Index.cshtml 」の中身を変更してみます。

@{
    ViewData["Title"] = "Home Page";
}

<div>
    <div class="text-center my-sm-5">
        <h1>TODO リスト</h1>
    </div>
    <div style="margin-bottom:20px;">
        <div>
            <button type="button" class="btn btn-outline-primary">タスク追加</button>
        </div>
    </div>
</div>
<table class="table">
    <thead>
        <tr>
            <th>
            </th>
            <th>
                プロジェクト名
            </th>
            <th>
                内容
            </th>
            <th>
                期限日
            </th>
            <th>
                登録日
            </th>
            <th>
                更新日
            </th>
            <th>
                編集・削除
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <input type="checkbox" class="form-check-input">
            </td>
            <td>
                ■▲●プロジェクト
            </td>
            <td>
                〇〇システムの提案書作成
            </td>
            <td>
                2023/04/25
            </td>
            <td>
                2023/04/20
            </td>
            <td>
                2023/04/20
            </td>
            <td>
                <button type="button" class="btn-primary">編集</button>
                <button type="button" class="btn-secondary">削除</button>
            </td>
        </tr>
        <tr>
            <td>
                <input type="checkbox" class="form-check-input">
            </td>
             <td>
                ABCプロジェクト
            </td>
            <td>
                〇〇の見積作成
            </td>
            <td>
                2023/05/18
            </td>
            <td>
                2023/04/03
            </td>
            <td>
                2023/04/20
            </td>
            <td>
                <button type="button" class="btn-primary">編集</button>
                <button type="button" class="btn-secondary">削除</button>
            </td>
        </tr>
        <tr>
            <td>
                <input type="checkbox" class="form-check-input">
            </td>
            <td>
                〇△□プロジェクト
            </td>
            <td>
                〇〇システムの改修
            </td>
            <td>
                2023/10/31
            </td>
            <td>
                2023/04/01
            </td>
            <td>
                2023/04/12
            </td>
            <td>
                <button type="button" class="btn-primary">編集</button>
                <button type="button" class="btn-secondary">削除</button>
            </td>
        </tr>
    </tbody>
</table>
<div>
    <nav>
        <ul class="pagination justify-content-center">
            <li class="page-item">
                <a class="page-link" href="#"><</a>
            </li>
            <li class="page-item"><a class="page-link" href="#">1</a></li>
            <li class="page-item"><a class="page-link" href="#">2</a></li>
            <li class="page-item"><a class="page-link" href="#">3</a></li>
            <li class="page-item">
                <a class="page-link" href="#">></a>
            </li>
        </ul>
    </nav>
</div>

実際のモック画面はこちらです。

モックを作成してみると、具体的なイメージが湧いてきました!
暫定的にこのモックでは、Modelを使わず画面上に決め打ちデータを表示させていますが、今後、Modelを使用してデータ受け渡しができるようにさせたいです。
また、タスクの追加・編集・削除ができるようにもさせたいです。

補足:最上位レベルのステートメントを使用するとは

実行可能なプログラムを書くとき、最初に呼び出される処理をエントリー ポイントと言います。
C# の場合、通常、Main という名前の静的メソッドを1個だけ書くことで、このメソッドがエントリー ポイントになります。ですが、 .NET 6 からデフォルトとして有効になった 「最上位レベルのステートメント」を使用することによって、 Program クラスとMain メソッドを明示的に含める必要がなくなりました。これは、コンパイラによってメイン プログラムのクラスおよびメソッド要素が生成されることを意味します。 

例えば、下記のように記述する必要があったコードは、

using System;

namespace Application
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}


Program クラスを作って、Main 関数を書いて・・・というような処理が不要となり、アプリケーションを構成するコードが簡略化できます。

Console.WriteLine("Hello, World!");


実際、今回生成された「Program.cs」ファイルに Main 関数 はないことが確認できます。

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

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

app.Run();

次回予告

今回は 、WEBページ のモック表示までを行いました。
次回は、Modelを使用して画面上にデータを表示できるように、モデルの追加・コントローラの変更・ビューの変更等を行います!