Microsoft Learn の Blazor 学習パスで Todo ページを作ったのに、/todo に移動すると 404…という壁はよくあります。原因は「@page の書き忘れ」や「ファイルがプロジェクトに認識されていない」など基本的なところが大半です。この記事ではテンプレート別の確認ポイントと、再現しやすい落とし穴を順番に潰す手順をまとめます。
まずは「404の種類」を切り分ける
同じ「404」に見えても、Blazor では大きく2パターンがあります。原因がまったく違うので、最初にどちらかを見極めると解決が早くなります。
| 見え方 | だいたいの発生場所 | よくある原因 | 最優先で見る場所 |
|---|---|---|---|
| ブラウザの「404 Not Found」/ IIS Express の404画面など、完全にサーバーのエラー | サーバーが /todo を「静的ファイルやエンドポイント」として解決できずに落ちている | 深いパスへの直接アクセス時のフォールバック未設定、ホスティング環境のリライト不足、URLのベースパス不一致 | Program.cs(MapFallback系)、ホスティング設定(IIS/Nginx/Apache/Static hosting) |
| アプリのレイアウトは表示されるが「このアドレスには何もありません」などの NotFound 表示 | Blazor ルーターが /todo を見つけられない(アプリ内で404扱い) | @page の誤り、ファイルが別プロジェクトに入っている、ビルド反映漏れ、Router/Routing設定の崩れ | Todo.razor の @page、配置場所(プロジェクト)、App.razor(Routes/Router) |
以降はこの2パターンをどちらもカバーするように、チェック項目を「上から順に」潰していきます。Microsoft Learn の手順どおりに進めている場合、最初の数項目で直ることがほとんどです。
最短で直すためのチェックリスト
時間をかけて深掘りする前に、まずは次のチェックを実施してください。特に @page と再ビルド は優先度が高いです。
| チェック | OKの状態 | NG例 | 直し方 |
|---|---|---|---|
Todo.razor に @page "/todo" がある | ファイル先頭付近に正しいルートが1行で書かれている | @page "todo"(スラッシュなし)/ @page "/todo "(末尾スペース)/ そもそも無い | @page "/todo" を追加し、余計な空白や誤字を削除 |
| ファイルが「正しいプロジェクト」に入っている | (Hosted構成なら)Client 側にページがある | Server プロジェクトに Todo.razor を作っている | Learn の手順に合わせて、ルーティング対象のプロジェクトへ移動 |
| ビルドに反映されている | 再起動後も /todo が開ける | Hot Reload で更新したつもりが反映されていない | 停止→Clean/Rebuild(または dotnet clean/build)→再実行 |
| NavMenu のリンク先が正しい | href="todo" または href="/todo" で意図どおり遷移 | href="todu" などタイポ、ベースパスがあるのに先頭スラッシュ固定 | リンクを修正。アプリがサブパス配下なら相対リンクを優先 |
| 「直打ち/リロードだけ404」かどうか | 直打ちでもリロードでも開ける | リンクで遷移はできるが、F5で404 | Program.cs の MapFallback、ホスティングのリライトを設定 |
Todo.razor の @page が正しいか確認する
Blazor で「ページ」として認識される最小条件は、コンポーネントに @page ディレクティブがあることです。Todo コンポーネントを作れていても、@page が無ければルーティング対象になりません。
@page はファイルの先頭付近に置く
どこに書いても動くケースはありますが、学習中は「先頭付近」に固定したほうが事故が減ります。余計な空白や全角記号の混入にも注意してください。
@page "/todo"
<h1>Todo</h1>
<p>ここに ToDo リストを作っていきます。</p>
ルート文字列の落とし穴
- 先頭スラッシュの有無:
"/todo"と"todo"は挙動が変わることがあります。迷ったら Learn の指示どおり"/todo"に揃えます。 - 末尾の空白:
@page "/todo "のように見えにくい空白が入ると別物になります。 - 全角スラッシュ:日本語 IME の影響で「/」になっていないか確認します。
- 大文字・小文字:環境や設定によっては区別されることがあります。教材は小文字で統一されることが多いので、
/todoを基本にします。
「配置場所」より大事なのは「どのプロジェクトに入れたか」
Learn の学習パスは、あなたが選んだテンプレート(Blazor Web App / Blazor Server / Blazor WebAssembly など)によってファイル構成が少しずつ違います。フォルダー名だけを合わせても、別プロジェクトに置いてしまうとルーティングで見つからず 404 になりやすいです。
テンプレート別:ページを置く場所の目安
| テンプレート | ページ(@page)の置き場の例 | 特にハマりやすい点 |
|---|---|---|
| .NET 8 以降の Blazor Web App | Components/Pages 配下(例:Components/Pages/Todo.razor) | 古い教材どおりに Pages を作ると迷いやすい(動くことも多いが、まずはテンプレに寄せる) |
| Blazor Server(.NET 6/7 など) | Pages 配下(例:Pages/Todo.razor) | App.razor の Router を壊すと全部404に見える |
| Blazor WebAssembly(Hosted) | Client プロジェクトの Pages 配下 | Server 側に作ってしまうミスが多い(Client の Router が見つけられない) |
| Blazor WebAssembly(Standalone) | Pages 配下(例:Pages/Todo.razor) | 別の静的サーバーで配信すると「直打ち/リロードだけ404」になりがち |
同じソリューション内に Server と Client がある構成(Hosted)では、Todo ページは基本的に Client に置きます。サーバー側にページを置いても、クライアント側のルーターがそのページを知らないため、NotFound になりやすいです。
プロジェクトが正しいか確認する簡単な方法
- Visual Studio のソリューションエクスプローラーで Todo.razor がどのプロジェクト配下にあるか を見ます。
- Hosted なら Client を右クリック→「追加」→「Razor コンポーネント」で作り直すのが確実です。
- ファイル移動後は、ビルドが通るか(エラーが出ないか)も必ず確認します。
再ビルドで「反映されていない」を潰す
Razor ファイルを追加した直後は、Hot Reload や watch がうまく追従せず「作ったのに存在しない」状態に見えることがあります。学習パスで詰まったら、一度確実にビルドし直すのが近道です。
Visual Studio での手順
- デバッグ実行を停止します。
- メニューから「ビルド」→「ソリューションのクリーン」→「ソリューションのリビルド」を実行します。
- もう一度デバッグ実行して
/todoにアクセスします。
CLI での手順
dotnet clean
dotnet build
dotnet run
| コマンド/操作 | 狙い | こんなときに効く |
|---|---|---|
| dotnet clean | 中間生成物の一掃 | 古いビルド成果物を掴んでいる気配がある |
| dotnet build | Razor のコンパイルを含めて再構築 | ファイル追加が反映されていない |
| dotnet run(再起動) | 実行プロセスを入れ替える | Hot Reload が不安定、実行中のアプリが古い |
NavMenu(メニュー)のリンク先を見直す
Learn の手順では NavMenu に Todo へのリンクを追加します。ここが間違っていると、@page が正しくても目的の URL に到達できません。
よく使われる NavLink の例
<NavLink class="nav-link" href="todo">
<span class="oi oi-list-rich" aria-hidden="true"></span> Todo
</NavLink>
- 相対リンク(todo)は、アプリがサブパス配下で動く場合にも比較的安全です。
- 絶対リンク(/todo)は分かりやすい一方、
/myappのようなベースパスが付く環境だと/todoが「サイト直下」扱いになり、意図とズレることがあります。
ローカル開発では気づきにくいのですが、将来 IIS やリバースプロキシ配下で公開する予定があるなら、まずは相対リンクで揃える方針もおすすめです(教材の指定がある場合は教材優先)。
App.razor のルーティング設定が壊れていないか確認する
ページを増やしている最中に、App.razor のルーティング部分を誤って消したり、学習教材のコードを別テンプレートにそのまま貼り付けたりすると、ページが認識されず 404 に見えることがあります。
.NET 8 の Blazor Web App(Routes コンポーネント)の例
テンプレートによって差はありますが、代表的には次のように <Routes /> が存在します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Blazor App</title>
<HeadOutlet />
</head>
<body>
<Routes />
Blazor Server / WASM(Router コンポーネント)の例
古いテンプレートや教材では Router が出てきます。AppAssembly が正しいかも重要です。
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
ポイント:Todo.razor が別プロジェクト(別アセンブリ)にある場合、Router からは見えません。その場合は AdditionalAssemblies を指定するなど「ルート探索範囲」を広げる必要があります。ただし Learn の Todo チュートリアルでは、通常は同一プロジェクト内に置く想定なので、まずは配置を教材に合わせるのが早いです。
「直打ちやリロードのときだけ404」の対処
ここが本当に初心者泣かせです。リンクで遷移したときは動くのに、ブラウザのアドレスバーに /todo を直接入力したり、F5(リロード)した瞬間に 404 になる場合、原因はたいてい「サーバー側が /todo を知らないのに、SPAとして index/host へ戻す設定が無い」ことです。
Blazor Server の場合(/_Host へフォールバック)
Program.cs に次のようなマッピングがあるか確認します(テンプレートで名前や順序が多少違うことがあります)。
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
Blazor WebAssembly の場合(index.html へフォールバック)
Hosted 構成なら Server 側、Standalone の静的配信ならホスティング側にフォールバックが必要です。ASP.NET Core でホストしているなら次の形が目安です。
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
app.MapControllers();
// 重要:クライアントルーティングへフォールバック
app.MapFallbackToFile("index.html");
静的ホスティング(IIS / Nginx / Apache)の例
学習が進んで公開を意識し始めたときに役立つよう、代表的なリライト例も載せておきます。ローカル開発では不要な場合もありますが、「公開したら /todo が404」になったときの定番解決策です。
IIS(web.config の例)
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="BlazorFallback" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Nginx(location の例)
location / {
try_files $uri $uri/ /index.html;
}
Apache(.htaccess の例)
RewriteEngine On
RewriteBase /
RewriteRule ^index\\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
まだ直らないときの追加チェック
上の項目で解決しない場合は、次の「見落としやすいポイント」を疑ってください。学習パスでは発生頻度は高くないものの、一度ハマると気づきにくい類です。
Todo.razor がプロジェクトに「含まれていない」
- ファイルをエクスプローラーで作って、Visual Studio のプロジェクトに取り込まれていない(ソリューションエクスプローラーに表示されない)
- 誤って「除外」されている
- 場所がプロジェクト外で、.csproj の包含規則に入っていない
対策としては、Visual Studio 上で「追加」から Razor コンポーネントを作成し直すのが最短です。
ファイル拡張子や名前の事故
Todo.razorのつもりがTodo.razor.txtになっているTodo.razorを作ったが、別にTodos.razorを編集していた- 日本語入力の影響で似た文字(全角/半角)が混ざっている
Windows だと気づきにくいので、拡張子表示を有効にして確認すると確実です。
ベースパス(<base href>)が変わっている
レイアウトやホストページを編集していると、<base href="/">(あるいは ~/)が意図せず変わり、相対リンクやルーティングの解決に影響することがあります。
| 場所 | 代表例 | 影響 |
|---|---|---|
| Blazor WebAssembly | wwwroot/index.html の <base href="/" /> | 相対 URL の解決が崩れ、/todo へ行けない・静的ファイルが読めない等 |
| Blazor Server | Pages/_Host.cshtml の <base href="~/" /> | ナビゲーションや静的ファイル参照が崩れる |
原因別に「次に何をすればいいか」まとめ
最後に、状況別に次アクションをまとめます。「どれを見ればいいか分からない」状態になったら、この表に戻ってください。
| 状況 | 可能性が高い原因 | 次にやること |
|---|---|---|
| /todo に行くとサーバーの404画面が出る | フォールバック未設定、ホスティングのリライト不足 | Program.cs の MapFallback(またはホスティング設定)を確認 |
| アプリ内の NotFound が出る | @page ミス、別プロジェクトに作成、ビルド反映漏れ | Todo.razor の @page と配置プロジェクトを確認→Clean/Rebuild |
| リンクでは開けるが、直打ち/リロードでだけ404 | SPA の深いリンク対策が不足 | MapFallbackToFile / MapFallbackToPage、または rewrite ルールを設定 |
| 自分では直したつもりなのに変わらない | キャッシュ、古いビルド、別の起動プロファイル | ハードリロード、bin/obj の削除、起動プロファイル確認 |
まとめ:まずは @page・配置・再ビルドを優先
Microsoft Learn の Blazor 学習パスで /todo が 404 になる原因は、ほとんどが ルーティング設定(@page)、正しいプロジェクト/配置、ビルド反映 のどれかです。まずはこの3点を「確実に」揃え、次に「直打ちやリロードだけ404」ならフォールバック設定を確認してください。これで学習パスの Todo ステップはスムーズに進められるはずです。

コメント