【ASP.NET Core入門#1】Program.csの仕組みとミドルウェアパイプラインを完全理解
【ASP.NET Core入門#1】Program.csの仕組みとミドルウェアパイプラインを完全理解
はじめに
この記事はYouTube動画「【ASP.NET Core入門#1】Program.csの仕組みとミドルウェアパイプラインを完全理解」の補足記事です。
動画で省略した細かい説明やコードの解説をここにまとめています。
🎬 動画はこちら → https://youtu.be/KP2uOPD0ebA
💻 サンプルコード → https://github.com/program-zunda/introduction_asp/tree/intro/episode-01
ASP.NET Coreとは
ASP.NET CoreはMicrosoftが開発した、クロスプラットフォーム対応のWebアプリケーションフレームワークです。
なぜASP.NET Coreを選ぶのか
1. クロスプラットフォーム
旧来のASP.NET FrameworkはWindowsのみで動作していましたが、ASP.NET CoreはWindows・Mac・Linuxどの環境でも動作します。
2. 高いパフォーマンス
TechEmpower Framework Benchmarks(Round 23 / 2025年2月)によると、ASP.NET Core(.NET 9)のPlaintextテストでのスループットはNode.jsのExpressの約100倍の数値を記録しています。
プロジェクトを作成する
ターミナルで以下のコマンドを実行します。
ソリューション作成
dotnet new sln -n ZundaService
ソリューション作成コマンドになります。
プロジェクト作成
dotnet new web -n ZundaNet
プロジェクト作成コマンドになります。
今回はASP.NET Core(Empty)と呼ばれるテンプレートで作成しています。
テンプレートとは、.NETが用意しているものでいくつか種類があります。
Web関連テンプレート一覧
| テンプレート名 | ショートネーム | 主な用途 |
|---|---|---|
| ASP.NET Core Empty | web |
最小構成。今回の動画で使用 |
| ASP.NET Core Web API | webapi |
REST API開発の定番 |
| ASP.NET Core API(AOT) | webapiaot |
Web APIのAOT(事前コンパイル)最適化版 |
| ASP.NET Core Web App (MVC) | mvc |
Model-View-Controller構成のWebアプリ |
| ASP.NET Core Web App |
webapp / razor
|
Razor Pagesベースのサーバーサイドレンダリング |
| Blazor Web App | blazor |
.NET 8で登場した統合Blazorモデル |
| Blazor WebAssembly | blazorwasm |
ブラウザ上でC#を動かすWASMアプリ |
| ASP.NET Core gRPC Service | grpc |
gRPCサービス向け |
| Worker Service | worker |
バックグラウンド処理・常駐サービス向け |
現在インストールされているテンプレートは以下のコマンドで確認できます。
dotnet new list
テンプレートの使い分け
web vs webapi
webは文字通り何も入っていない空の状態です。
webapiはREST APIを作るための設定(OpenAPI / Swaggerのサポートなど)があらかじめ含まれています。
APIサーバーを作りたい場合はwebapiの方がスムーズに始められます。
# 最小構成(今回使用)
dotnet new web -n MyApp
# REST API向け
dotnet new webapi -n MyApi
ソリューションへの追加
dotnet sln add ZundaNet/ZundaNet.csproj
ソリューションに作成したプロジェクトを追加するコマンドになります。
ここまでコマンドで実行してきましたが、IDEからこれらを代用することも可能です。
やり方はIDE次第ですので、今回は割愛させていただきます。
なぜソリューションを作るのか
dotnet new webだけでも動くコードは書けます。
それでもソリューションを作る理由は、後から複数のプロジェクトを追加することを見越しているからです。
本格的なASP.NET Coreのアプリケーションは、1つのプロジェクトだけで完結することはほとんどありません。
たとえば本シリーズの第5回で扱うクリーンアーキテクチャでは、次のように役割ごとにプロジェクトを分けます。
ZundaService.sln
├── ZundaNet/ # エントリポイント・ルーティング
├── ZundaLogic/ # ビジネスロジック
├── ZundaDomain/ # エンティティ・ドメインルール
└── ZundaInfrastructure/ # DB・外部サービスとの接続
このとき、ソリューション(.sln)がこれらのプロジェクトをまとめる「フォルダ」の役割を果たします。
IDEでもソリューション単位でプロジェクトを開くため、最初から作っておく習慣をつけておくとスムーズです。
生成されるファイル構成
ZundaService/
├── ZundaService.sln # ソリューションファイル
└── ZundaNet/
├── Program.cs # アプリの心臓部
├── appsettings.json # 設定ファイル
├── appsettings.Development.json # 開発環境専用の設定
└── ZundaNet.csproj # プロジェクト設定
| ファイル | 役割 |
|---|---|
Program.cs |
アプリ全体の設定・起動処理 |
appsettings.json |
DB接続先・ログレベルなどの設定値 |
*.csproj |
使用するライブラリ・.NETバージョンの定義 |
Program.csを読み解く
生成されたProgram.csは以下のようになっています。
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
たった4行ですが、ここにASP.NET Coreの核心が詰まっています。順番に見ていきましょう。
1. builderの生成
var builder = WebApplication.CreateBuilder(args);
WebApplicationBuilderのインスタンスを生成します。
builderはアプリの「設計図」を持つ存在で、以下のものを登録する役割を担います。
- Services:DIコンテナへの部品登録(詳細は第2回)
-
Configuration:
appsettings.jsonなどの設定読み込み - Logging:ログの出力設定
- Host:Webサーバー(Kestrel)の設定
2. アプリのビルド
var app = builder.Build();
builderの設定をもとにWebApplicationのインスタンスを生成します。
この時点でDIコンテナが確定し、サービスが解決可能な状態になります。
3. ルーティングの定義
app.MapGet("/", () => "Hello World!");
/(トップページ)へのGETリクエストに対して、文字列を返す処理を定義しています。
これはMinimal APIと呼ばれる記法です。
| メソッド | 対応するHTTPメソッド |
|---|---|
MapGet |
GET |
MapPost |
POST |
MapPut |
PUT |
MapDelete |
DELETE |
4. アプリの起動
app.Run();
Webサーバー(Kestrel)を起動し、リクエストの受付を開始します。
この行はブロッキング呼び出しのため、アプリが停止するまで処理が戻りません。
ミドルウェアパイプライン
ASP.NET Coreの核心的な概念のひとつです。
ミドルウェアとは
リクエストとレスポンスの間に挟まる処理のことです。
複数のミドルウェアがチェーン状に連なり、リクエストを順番に処理します。
Request → [Logging] → [認証] → [Routing] → Response
ミドルウェアの登録
app.UseHttpsRedirection(); // HTTPSへのリダイレクト
app.UseAuthentication(); // 認証
app.UseAuthorization(); // 認可
独自ミドルウェアを作る(補足)
app.Use()を使うと独自の処理を挟むことができます。
app.Use(async (context, next) =>
{
// リクエスト処理前
Console.WriteLine($"Request: {context.Request.Path}");
await next(context); // 次のミドルウェアへ
// レスポンス処理後
Console.WriteLine($"Response: {context.Response.StatusCode}");
});
動かしてみる
dotnet run
起動後、ターミナルに表示されたURL(例:http://localhost:5000)をブラウザで開くと「Hello World!」が表示されます。
まとめ
| 概念 | 役割 |
|---|---|
builder |
アプリの設計図。Services・Configuration・Loggingを登録 |
.Build() |
設計図からアプリを生成。DIコンテナが確定する |
app |
実行可能なWebアプリ。MiddlewareとRoutingを設定 |
.Run() |
Webサーバーを起動しリクエスト待受を開始 |
| ミドルウェア | リクエスト/レスポンスに挟まる処理。登録順が重要 |
次回予告
第2回では**依存性の注入(DI)**を深掘りします。
-
AddScoped/AddTransient/AddSingletonの違いとライフサイクル - Optionsパターンによる型安全な設定取得
- 標準
ILoggerの使い方
🎬 動画:作成中
📝 記事:作成中
Discussion