ASP.NET MVC（.NET Framework）記載まとめ　【初学者編】2


##    はじめに
C#のWebアプリケーションのフレームワークである
ASP.NET MVCプロジェクト（.NET Frameworkベース）を作成手順まとめです。

------------------------------------
[前回の記事はこちら](https://qiita.com/nano357/items/bf22da5b7f19a4a0981f)

--------------------------------------------------------------


## <font color="green">①プロジェクトの作成</font>

   1･･･ Visual Studio Installerを開く
````
・説明：インストール済みのVisual Studioがある場合、Visual Studio Installerを開き、変更をクリックして必要なワークロードを追加します。
````
   2･･･ 必要なワークロードの選択
````
「ASP.NETとWeb開発」
         ・説明：ASP.NET MVCアプリケーション開発に必要な機能

「.NETデスクトップ開発」
         ・説明：デスクトップアプリケーションと連携する場合に必要なツール
````
   3･･･ 個別のコンポーネント
````
「.NET Framework 4.7.2 Targeting Pack」
         ・説明：ASP.NET MVCプロジェクト (.NET Framework) をターゲットとするための必須コンポーネント

「Entity Framework 6 Tools」
         ・説明： データベースの操作が必要な際に便利です。
````
   4･･･ 新しいプロジェクトの作成「新しいプロジェクトの作成」

   5･･･ プロジェクトテンプレートの選択「ASP.NET Webアプリケーション (.NET Framework)」

   6･･･ プロジェクトの設定
      プロジェクト名を「SumDataManagementApp」とし、場所をC:\temp\ASP.NETに指定します。
      
   7･･･ 「テンプレートの選択」で「MVC」を選択し、「認証なし」を選択して「作成」をクリックします。

--------------------------------------------------------------

## <font color="green">②プロジェクトのファイル構造</font>
````
SumDataManagementApp/
 ├── Properties/          # アプリケーションのプロパティ（バージョン、アセンブリ情報など）
 ├── App_Data/            # データベースなどのアプリケーションデータを格納
 ├── App_Start/           # アプリケーション起動時の設定（RouteConfig、Startupなど）
 ├── Content/             # CSSファイル、画像などの静的リソース
 ├── Controllers/         # コントローラー（アプリのロジックを管理）
 ├── Data/                # データベースアクセス用のコンテキスト
 ├── Models/              # データモデル（ビジネスロジック）
 ├── Views/               # ビュー（HTMLを生成）
 ├── Scripts/             # JavaScriptファイル
 ├── Global.asax          # アプリケーションのライフサイクル管理
 ├── Web.config           # アプリケーションの設定（接続文字列、エラーハンドリング等）
 └── packages.config      # 使用しているNuGetパッケージの管理

````

--------------------------------------------------------------

## <font color="green">③重要ファイルとフォルダの解説</font>
#### 1.Global.asax
・アプリケーション全体のライフサイクルイベント（アプリケーションの開始や終了など）を管理します。
・Global.asax.cs の Application_Start メソッドで、ルーティングやバンドル設定を行います。
```csharp
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace SumDataManagementApp  // ここが名前空間
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            // アプリケーション内のすべてのエリアの登録
            AreaRegistration.RegisterAllAreas();
            /* エリアを登録し、それに対応するルーティングを設定する */

            // グローバルフィルタ（例：認証、エラーハンドリング）の設定
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            /* グローバルフィルタをすべてのコントローラに適用 */

            // ルート設定の初期化
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            /* 依存関係の注入や初期設定をここで行う
               アプリケーション内の URL ルーティング設定を行います。 */

            // スクリプトやスタイルのバンドル設定
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            /* JavaScript や CSS のバンドルを設定します。
               これにより、複数のファイルが1つにまとめられ、
               リクエストの数が減るため、
               アプリケーションのパフォーマンスが向上します。 */
        }
    }
}

````
・説明：Global.asax.cs 内で Application_Start メソッドを定義し、アプリケーションが起動する際に、ルーティングの設定を初期化します。

------------------------------------

#### 2.App_Startフォルダ
・RouteConfig.cs: ルーティングの設定を管理。アプリのURLに基づいてどのコントローラーとアクションを呼び出すかを定義します。
```csharp
using System.Web.Mvc;
using System.Web.Routing;

namespace SumDataManagementApp
{
    /*
     * :RouteConfigクラスは、ASP.NET MVCアプリケーションのルーティング
     *  （URLをコントローラーやアクションメソッドにマッピングする機能）を
     *  定義するためのクラスです。
     * 
     * :このクラスは、アプリケーションがどのURLパターンに対して
     *  どのコントローラーやアクションメソッドを呼び出すかを
     *  決定するために使用されます。
     */

    public class RouteConfig
    {

        /*
         *:RegisterRoutesメソッドは、ルートの定義を行います。
         *
         *:RouteCollection routes は、ルートを格納するコレクションです。
         * このコレクションにルートを追加することで、
         * アプリケーションのURLルーティングが決まります。
         *
         * static修飾子により、このメソッドはインスタンスを作成せずに
         * 直接呼び出すことができます。
         */
         
        public static void RegisterRoutes(RouteCollection routes)
        {

            
            /*
             *:IgnoreRouteメソッドは、特定のパターンにマッチするURLを
             * ルーティングから除外するために使用します。
             *
             *:RouteCollection routes は、ルートを格納するコレクションです。
             * この例では、.axdリソース
             * （例えば、Trace.axdなどのASP.NETのトレースハンドラ）に
             * アクセスするURLが除外されます。これにより、
             * .axdファイルがアプリケーションのルート処理によって
             * 処理されないようにしています
             */
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            /*
             *:MapRouteメソッドは、新しいルートを定義するために使用されます。
             *
             *:第一引数: name: "Default"
             * ルートの名前を指定します。
             * このルートは「Default」という名前で定義されています。
             * 名前をつけることで、後でルートを参照したり
             * 変更したりする際に便利です。
             * 
             * :第二引数: url: "{controller}/{action}/{id}"
             *  ルートのURLパターンを指定します。
             *  {controller}、{action}、**{id}**はプレースホルダで、
             *  URLの一部に応じて実際の値に置き換えられます。
             *  
             *  {controller}: 使用するコントローラーの名前
             *  {action}: コントローラーの中のメソッド（アクション）の名前
             *  {id}: オプションのパラメーターとして、
             *  IDなどの値を指定できます。
             * 
             * :第三引数: defaults: 
             *           new { controller = "Home", 
             *           action = "Index", id = UrlParameter.Optional }
             * ルートに対してデフォルトの値を指定しています。
             * 名前をつけることで、
             * 後でルートを参照したり変更したりする際に便利です。
             * 
             * controller = "Home":
             *  デフォルトのコントローラーはHomeController。
             * action = "Index":
             *  デフォルトのアクションはIndexメソッド。
             * id = UrlParameter.Optional: 
             *  idパラメーターは任意で、省略可能です。
             */
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "SumDatas", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}
````
##### RouteConfig.cs 全体の意味
このコードは、アプリケーションのデフォルトのルーティングを設定しています。
URLが特定のコントローラーやアクションにマッピングされる方法を定義し、
次のようなデフォルトルートを設定しています。
````
  URLパターン: {controller}/{action}/{id}
　　　例: /Home/Index/123 → HomeControllerのIndexアクションが実行され、idは123。
　　　デフォルトでは、コントローラーがHome、アクションがIndexに設定され、idは省略可能です。
````

------------------------------------

#### 3.Web.config
アプリケーションの設定ファイルで、接続文字列やエラーハンドリング、認証、カスタム設定を行います。
```xml
<!-- ここに接続文字列を移動 -->
<connectionStrings>
    <!-- デフォルトのデータベース接続情報を設定 -->
    <add name="DefaultConnection"
         connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=SumDataManagementApp;Integrated Security=True"
         providerName="System.Data.SqlClient" />
</connectionStrings>
````
・コメントの説明
````
データベース接続文字列を指定するためのセクションです。このセクションに、アプリケーションがアクセスするデータベースの情報を格納します。
````
name="DefaultConnection":
````
この接続文字列の識別名です。アプリケーション内で使用する際にこの名前で呼び出します。
````
connectionString:
````
実際の接続情報です。
````
Data Source=(LocalDb)\MSSQLLocalDB:
````
ローカルの SQL Server インスタンスを指定しています。
````
Initial Catalog=SumDataManagementApp:
````
接続するデータベースの名前です。ここでは SumDataManagementApp というデータベースに接続します。
````
Integrated Security=True:
````
Windows 認証を使ってデータベースに接続します。
````
providerName="System.Data.SqlClient":
````
データアクセスプロバイダーの名前です。System.Data.SqlClient は SQL Server 用のプロバイダーです。
````
この接続文字列を使用することで、ASP.NET アプリケーションが SumDataManagementApp データベースにアクセスできます。

--------------------------------------------------------------

## <font color="green">③データモデルの作成</font>
#### SumDataクラスの作成
Modelsフォルダーを右クリックし、「追加」→「クラス」を選択し、"SumData.cs"を追加します。以下のコードを追加します。
```C#
using System;
using System.ComponentModel.DataAnnotations;

/**
 * SumDataモデルはデータベースのSumDataテーブルを表すクラス。
 * 
 * 各プロパティはテーブルのカラムに対応しており、
 * プライマリキー、計算対象の数値、計算結果、作成日時、更新日時を持つ。
 */
namespace SumDataManagementApp.Models
{
    public class SumData
    {
        public int Id { get; set; }  // プライマリキー

        [Required(ErrorMessage = "Numberフィールドは必須です。")]
        [Range(1, 100, ErrorMessage = "Numberは1から100の間で入力してください。")]
        public int Number { get; set; }  // 計算対象の数値

        public int Result { get; set; }  // 計算結果
        public DateTime CreatedDate { get; set; }  // 作成日時
        public DateTime UpdatedDate { get; set; }  // 更新日時
    }
}
````
https://qiita.com/SY81517/items/c90a5a78b06ed46c24de

--------------------------------------------------------------
#### データベースコンテキストの作成
Dataフォルダーに "SumDataManagementAppContext.cs" を作成し、以下のコードを追加します。
```C#
using SumDataManagementApp.Models;
using System.Data.Entity;

/**
 * SumDataManagementAppContextはデータベースコンテキストを表すクラス。
 * 
 * DbContextを継承し、SumDataテーブルを操作するDbSetプロパティを持つ。
 */
namespace SumDataManagementApp.Data
{
    public class SumDataManagementAppContext : DbContext
    {
        // "DefaultConnection" という名前の接続文字列を使用
        public SumDataManagementAppContext() : base("DefaultConnection")
        {
        }

        // SumData テーブルに対応する DbSet
        public DbSet<SumData> SumDatas { get; set; }
    }
}

````
https://qiita.com/Nossa/items/b6d84aeb134abc85f027

--------------------------------------------------------------
## <font color="green">④コントローラーの作成</font>
#### SumDatasControllerの作成
Controllersフォルダーに新しいコントローラー "SumDatasController.cs" を追加し、以下のコードを実装します。
```C#
using System;
using System.Linq;
using System.Web.Mvc;
using SumDataManagementApp.Models;
using SumDataManagementApp.Data;
using System.Data.Entity.Infrastructure;  // DbUpdateExceptionをキャッチするために追加

namespace SumDataManagementApp.Controllers
{
    public class SumDatasController : Controller
    {
        // データベースコンテキストのインスタンスを作成
        private readonly SumDataManagementAppContext _context = new SumDataManagementAppContext();

        // GET: SumDatas
        public ActionResult Index()
        {
            try
            {
                // SumDataのリストを取得し、ビューに渡す
                var sumData = _context.SumDatas.ToList();
                return View(sumData);  // IndexビューにSumDataのリストを渡す
            }
            catch (Exception ex)
            {
                // エラーメッセージを表示し、ログを出力
                ModelState.AddModelError("", "データの取得中にエラーが発生しました。");
                Console.WriteLine(ex.Message);  // エラーログを出力
                return View("Error");  // エラー時はエラービューを返す
            }
        }

        // GET: SumDatas/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: SumDatas/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(SumData sumData)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    // 計算結果を設定
                    sumData.Result = sumData.Number * 2;

                    // 作成日時と更新日時を設定
                    sumData.CreatedDate = DateTime.Now;
                    sumData.UpdatedDate = DateTime.Now;

                    // データを追加し保存
                    _context.SumDatas.Add(sumData);
                    _context.SaveChanges();

                    return RedirectToAction("Index");
                }
                catch (DbUpdateException ex)
                {
                    ModelState.AddModelError("", "データベース更新中にエラーが発生しました。");
                    Console.WriteLine(ex.InnerException?.Message);
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", "データ作成中にエラーが発生しました。");
                    Console.WriteLine(ex.Message);
                }
            }

            return View(sumData);
        }
    }
}
````
https://aspnet.keicode.com/basic/security-csrf-mvc-razor.php#google_vignette

--------------------------------------------------------------

## <font color="green">⑤ ビューの作成</font>
#### Indexビュー
Views/SumDatas/Index.cshtml に以下のコードを追加します。
```C#
@model IEnumerable<SumDataManagementApp.Models.SumData>

<h1>Sum Data</h1>

<p>
    <a href="@Url.Action("Create")">Create New</a>  <!-- 新規作成リンク -->
</p>

<table class="table">
    <thead>
        <tr>
            <th>Number</th>
            <th>Result</th>
            <th>Created Date</th>
            <th>Updated Date</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>@item.Number</td>
                <td>@item.Result</td>
                <td>@item.CreatedDate</td>
                <td>@item.UpdatedDate</td>
            </tr>
        }
    </tbody>
</table>
````
#### Createビュー
Views/SumDatas/Create.cshtml に以下のコードを追加します。
```C#
@model SumDataManagementApp.Models.SumData

<h1>Create Sum Data</h1>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <div class="form-group">
        @Html.LabelFor(model => model.Number)
        @Html.EditorFor(model => model.Number)
        @Html.ValidationMessageFor(model => model.Number, "", new { @class = "text-danger" })
    </div>
    <button type="submit" class="btn btn-primary">Create</button>
}

<a href="@Url.Action("Index")">Back to List</a>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
````

--------------------------------------------------------------


## 元サイト（サブアカウント）

   https://qiita.com/nekoozi/items/31f9ed52b3180b711707
   
------------------------------------

   次回：ASP.NET MVC（.NET Framework）記載まとめ　【初学者編】3

https://qiita.com/nano357/items/d8564fe79c600127eb45


--------------------------------------------------------------