Visual Studio の IIS Express では ASP.NET Web API が正常に動くのに、同じプロジェクトを IIS 10 に配置すると「404 – ファイルまたはディレクトリが見つかりません」と表示される――このギャップでハマる開発者はとても多いです。本記事では、「なぜ IIS に載せると 404 になるのか」「どう設定すれば確実に動くのか」を、実際の URL 例(/api/values/GetDispatchData)を使いながら丁寧に解説します。
IIS では動かないのに IIS Express では動く理由
まず押さえておきたいのは、同じアプリでも IIS Express と IIS 10 は別物だという点です。
- IIS Express:Visual Studio が自動で最適な構成を用意してくれる「開発用ミニ IIS」
- IIS 10:Windows に標準搭載された「本番用 Web サーバー」。機能やアプリケーション プール設定を自分で整える必要あり
そのため、IIS 10 にそのままソースをコピーしただけでは、必要なモジュールが有効になっていなかったり、ルーティング設定が反映されていなかったりして、結果として 404 になります。
| 環境 | URL 例 | 挙動 | 主な理由 |
|---|---|---|---|
| Visual Studio(IIS Express) | http://localhost:49822/api/values/GetDispatchData | 正常に JSON が返る | VS が Web.config・アプリ プール・ハンドラーを自動調整している |
| IIS 10(本番 / ローカル IIS) | http://localhost/MVCAPI/api/values/GetDispatchData | 404 – File or directory not found | 発行物が不完全 or IIS 機能不足 or ルート/プール設定ミス |
つまり「IIS Express で動く = IIS でもそのまま動く」ではありません。IIS で動かすための準備をきちんと行う必要があります。
404 でも「ファイルがない」とは限らない
IIS の 404 メッセージに「File or directory not found」と書かれているため、つい「ファイルを置き忘れたのかな?」と思いがちですが、ASP.NET Web API の場合は少し事情が違います。
- Web API の URL(
/api/values/GetDispatchData)は物理ファイルではなくルーティングで解決される - そのルーティングを理解するのは、IIS 本体ではなくASP.NET ランタイム(Managed Pipeline)
- ASP.NET ランタイムに処理が渡っていないと、「ファイルがない」という 404 に見える
つまり、404 の本当の原因は「ファイルがない」のではなく、ASP.NET にリクエストが届いていない(または届いてもルートにマッチしていない)ことがほとんどです。
最初にやるべきこと:発行(Publish)で正しく配置する
ソースをそのままコピペして IIS の物理パスに置くと、以下のような問題が起きがちです。
binフォルダーに必要な DLL が揃っていない- 本来の
web.configではなく、開発用の設定ファイルを置いてしまう - デバッグ ビルドのまま配置され、挙動が開発環境と微妙に変わる
これらを避けるため、必ず Visual Studio の「発行(Publish)」機能を使って配置します。
フォルダー プロファイルで発行する手順
- Visual Studio で Web API プロジェクトを開く
- ソリューション エクスプローラーでプロジェクトを右クリック → [発行]
- 発行先として [フォルダー] を選択し、出力先フォルダー(例:
C:\deploy\MVCAPI)を指定 - 構成を Release に設定
- [発行] を実行
発行が完了したら、出力フォルダーに以下のような構造ができていることを確認します。
| パス | 存在必須 | 説明 |
|---|---|---|
発行先\ | web.config | IIS が読み込む設定ファイル。ハンドラー マッピングやルーティング設定が入る |
発行先\bin\ | プロジェクト名の DLL | Web API コントローラ等を含むメイン DLL |
発行先\bin\ | 依存ライブラリ | Json.NET など NuGet パッケージの DLL 群 |
このフォルダーを、そのまま IIS のサイト / アプリケーションの物理パスとして指定します。ソースコードのフォルダーではなく、あくまで「発行フォルダー」を使う点が重要です。
Windows の機能で ASP.NET 4.x を有効化する
Windows 側で ASP.NET ランタイムが有効化されていないと、IIS は拡張子なし URL(/api/... など)を ASP.NET に渡せず、404 になります。
必要な機能を有効にする手順
- コントロール パネル → [プログラムと機能] → [Windows の機能の有効化または無効化]
- [インターネット インフォメーション サービス] を展開
- [World Wide Web サービス] → [アプリケーション開発機能] を展開
- 以下にチェックを入れる
- ASP.NET 4.8
- .NET Extensibility 4.8
- ISAPI 拡張
- ISAPI フィルター
- あわせて、[静的コンテンツ] と [既定のドキュメント] も有効にしておくと無難
| 機能名 | 役割 | 不足時の症状 |
|---|---|---|
| ASP.NET 4.8 | ASP.NET 4.x アプリを動かす本体 | 拡張子なし URL が 404.2 / 404.3 になりやすい |
| .NET Extensibility 4.8 | ASP.NET と IIS の連携を担う | Managed ハンドラーが動かず 404 / 500 になる |
| ISAPI 拡張 / フィルター | 古典的な ASP.NET 連携に必要 | 拡張子付き URL も ASP.NET に届かない |
これらが有効になっていると、ExtensionlessUrlHandler-Integrated-4.0 というハンドラーが使えるようになり、/api/values のような拡張子なし URL も ASP.NET Web API に渡されるようになります。
アプリケーション プールの設定を確認する
次に確認すべきなのが、IIS の アプリケーション プールです。ここが Classic モードだったり、.NET CLR バージョンが違っていたりすると、ルーティングがまったく動きません。
推奨設定
| 設定項目 | 推奨値 | ポイント |
|---|---|---|
| .NET CLR バージョン | v4.0 | ASP.NET Web API は .NET 4.x ベースのため |
| マネージド パイプライン モード | 統合(Integrated) | Classic だと Web API のルーティングが機能しないことが多い |
| 32 ビット アプリケーションの有効化 | 環境に合わせて true/false | アプリが x86 限定ライブラリに依存している場合のみ有効化 |
設定変更の手順
- IIS マネージャーを開く
- 左ペインの [アプリケーション プール] をクリック
- 対象のアプリケーション プール(例:
MVCAPIAppPool)を右クリック → [基本設定] - [.NET CLR バージョン] = v4.0 を選択
- [マネージド パイプライン モード] = 統合 を選択
Classic のままだと、Web API が内部で使っているルーティング(System.Web.Http)が正しく動かず、/api/... にアクセスしても ASP.NET に到達しないため、404 のままになってしまいます。
サイト / アプリケーションを正しく作成する
「既定の Web サイトに置けばいいのかな?」と何となく設定してしまうと、URL のパスがずれて 404 になることがあります。ここでは、よくある構成を例に具体的な URL と対応付けてみます。
既定の Web サイト配下にアプリケーションを作る例
- IIS マネージャーで [既定の Web サイト] を右クリック → [アプリケーションの追加]
- [エイリアス] に
MVCAPIと入力 - [アプリケーション プール] に先ほど設定した v4.0 / 統合のプールを選択
- [物理パス] に「発行したフォルダー」(例:
C:\deploy\MVCAPI)を指定 - [OK] で作成
この構成の場合、実際の URL は以下のようになります。
| 用途 | URL | 説明 |
|---|---|---|
| サイト ルート | http://localhost/MVCAPI/ | アプリケーション ルート。ここが表示されれば IIS と発行はほぼ成功 |
| Web API コントローラ | http://localhost/MVCAPI/api/values | ルート設定によってはこの URL で JSON が返る |
| 今回のメソッド | http://localhost/MVCAPI/api/values/GetDispatchData | アクション名を含むルートの場合 |
よくあるミスとして、IIS Express での URL(例:http://localhost:49822/api/values/GetDispatchData)をそのままブラウザーに打ち込み、「IIS では 404 だ」と勘違いしてしまうパターンがあります。IIS に配置した場合は、必ずエイリアス(/MVCAPI など)を含めた URL でアクセスしましょう。
Web API のルーティング設定を見直す
質問のケースでは、次のような URL を叩いています。
http://localhost/MVCAPI/api/values/GetDispatchData
この URL を解決するには、アクション名を含むルート テンプレートが必要です。App_Start/WebApiConfig.cs を開き、以下のような設定になっているか確認しましょう。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// 属性ルーティングを使う場合
config.MapHttpAttributeRoutes();
// アクション名を含むルート
config.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// 必要であれば、アクション名なしのルートも追加可能
// config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
// );
}
}
コントローラの例
ValuesController が次のようになっていることも確認します。
public class ValuesController : ApiController
{
[HttpGet]
public IHttpActionResult GetDispatchData()
{
var data = new
{
Id = 1,
Message = "IIS からも取得できました"
};
return Ok(data);
}
}
- クラス名は
ValuesController(末尾がController) - メソッド名は
GetDispatchData [HttpGet]属性を付けておくと、HTTP メソッドとの対応が明示的になりトラブルが減る
なお、属性ルーティング([Route("api/values/getdispatchdata")] など)を使っている場合は、実際の URL と綴りが完全に一致しているかも確認しましょう。大文字小文字は基本的に区別されませんが、短い単語のタイプミスは見落としやすいポイントです。
動作確認のおすすめ手順
設定を一通り見直したら、次の順序で動作確認すると原因切り分けがきれいにできます。
- アプリケーション ルートを確認
- URL:
http://localhost/MVCAPI/ - ここで 404 なら「発行フォルダーの指定ミス」「
web.configの読み込みエラー」など、もっと手前の問題
- URL:
- コントローラ単位で確認
- URL:
http://localhost/MVCAPI/api/values - JSON や配列が返るなら、Web API 自体は動いていると判断できる
- URL:
- 目的アクションで確認
- URL:
http://localhost/MVCAPI/api/values/GetDispatchData - ここだけ 404 になる場合は、ルーティング定義とアクション名の不一致が濃厚
- URL:
ブラウザーだけでなく、Postman や curl などのツールを使ってレスポンスの HTTP ステータスやヘッダーを確認すると、より正確に状況を把握できます。
それでも 404 のときのチェックポイント
ここまでの設定を行っても 404 が解消しない場合、IIS のログやハンドラー マッピングを確認して原因を追い込みます。
IIS ログで 404 のサブステータスを確認する
IIS のログは通常、次のフォルダーに出力されています。
C:\inetpub\logs\LogFiles\W3SVC<nnn>\
ログファイルをメモ帳などで開き、該当リクエストの行を探します。末尾付近に 404 2 のような形で ステータスコード + サブステータス が記録されています。
| サブステータス | 意味(ざっくり) | 対処の方向性 |
|---|---|---|
| 404.0 | 素の 404。ファイル/ルートが見つからない | URL の間違い / ルーティング設定の見直し |
| 404.2 | Web サービス拡張 / ハンドラーが無効 | ASP.NET 4.8 などの Windows 機能やアプリ プール設定を再確認 |
| 404.3 | MIME タイプ / ハンドラーの構成が不適切 | ハンドラー マッピングと web.config の <handlers> セクションを確認 |
特に 404.2 / 404.3 が出ている場合は、「アプリ自体」ではなく「IIS と ASP.NET の橋渡し部分」に問題があると考えましょう。
ハンドラー マッピングを確認する
IIS マネージャーでサイトを選択し、[機能ビュー] から [ハンドラー マッピング] を開きます。ここに以下のようなエントリが存在するか確認します。
- ExtensionlessUrlHandler-Integrated-4.0
- PageHandlerFactory-Integrated-4.0
これらが存在しない/無効になっている場合、拡張子なしの URL が ASP.NET に届かず、いくら Web API 側を修正しても 404 のままになります。
WebDAV の無効化
WebDAV を使っていない場合、WebDAV モジュールが Web API のルートより先にリクエストを横取りし、405 や 404 を返すことがあります。
- サイトの [機能ビュー] → [モジュール] で、WebDAVModule を一時的に削除してみる
- または
web.configの<modules>セクションで WebDAV を除外する
WebDAV を利用していないのであれば、機能ごと無効化しておくとトラブルが減ります。
依存 DLL / ビルド設定の確認
手動コピーした場合にありがちなのが、「ローカルでは参照できていた DLL をコピーし忘れる」ケースです。発行機能を使っていれば基本的に解消されますが、念のため以下も確認しましょう。
binフォルダーに、NuGet パッケージの DLL が一式揃っているか- ターゲット フレームワークが .NET Framework 4.x になっているか
- デバッグ ビルドとリリース ビルドで挙動が変わらないか
DLL が不足している場合は、実行時に 500 エラーになることもありますが、ルーティング処理より手前で落ちると結果的に 404 に見えることもあるため要注意です。
背景知識:IIS Express と IIS の違いを理解する
最後に、なぜ「IIS Express では何も考えなくても動くのに、IIS 本番ではちょっとした違いで 404 になるのか」を簡単に整理しておきます。
| 項目 | IIS Express | IIS 10(フル IIS) |
|---|---|---|
| 用途 | 開発用(Visual Studio 同梱) | 開発〜本番までのホスト |
| 設定 | プロジェクト ファイルと連動して VS が自動生成 | 手動でサイト / アプリケーション / プール / 機能を設定 |
| モジュール構成 | ASP.NET Web API に必要なモジュールが最初から有効 | インストール時の選択やロールによっては無効 |
| URL ベース | http://localhost:ポート/ にアプリが直接ぶら下がる | http://localhost/エイリアス/ など階層構造を意識する必要あり |
今回のようなケースでは、「発行ではなく手動コピー」+「IIS 側の機能やプール設定の不足」 が重なり、IIS Express と IIS の差が表面化していると考えられます。
再発防止用チェックリスト
同じ落とし穴にはまり続けないよう、ASP.NET Web API を IIS に載せるときのチェックリストをまとめておきます。
| カテゴリ | チェック項目 | 確認結果メモ |
|---|---|---|
| 発行 | Visual Studio の発行(Release / フォルダー)で配置している | |
| 発行 | 発行フォルダー直下に web.config と bin が存在する | |
| Windows 機能 | ASP.NET 4.8 / .NET Extensibility 4.8 / ISAPI 拡張 / ISAPI フィルターが有効 | |
| アプリ プール | .NET CLR v4.0 / 統合モードのアプリケーション プールを使っている | |
| サイト構成 | URL に正しいエイリアス(例:/MVCAPI)を含めてアクセスしている | |
| ルーティング | api/{controller}/{action}/{id} など目的の URL に合ったルートが設定されている | |
| ログ | IIS ログのサブステータス(404.2 / 404.3 等)を確認した | |
| ハンドラー | ExtensionlessUrlHandler-Integrated-4.0 が有効 | |
| その他 | WebDAV など不要なモジュールが邪魔していない |
まとめ:IIS で ASP.NET Web API の 404 を解消する最短手順
最後に、本記事で紹介した内容を「最短で試すべき手順」として整理します。
- Visual Studio で発行する
- 発行先をフォルダーに設定し、Release 構成で発行
- 発行フォルダー直下に
web.configとbinがあることを確認
- Windows の機能を有効化
- ASP.NET 4.8 / .NET Extensibility 4.8 / ISAPI 拡張 / ISAPI フィルター にチェック
- アプリケーション プールを v4.0・統合モードに
- .NET CLR バージョン = v4.0
- マネージド パイプライン モード = 統合
- サイト / アプリを作成し、物理パスに発行フォルダーを指定
- 既定の Web サイト配下に
MVCAPIなどのエイリアスでアプリケーションを追加 - URL は
http://localhost/MVCAPI/...になることを意識
- 既定の Web サイト配下に
- ルーティング設定を見直す
api/{controller}/{action}/{id}など、目的の URL に合ったルート テンプレートを設定ValuesController.GetDispatchData()に[HttpGet]を付ける
- 順番に URL を叩いて確認
http://localhost/MVCAPI/http://localhost/MVCAPI/api/valueshttp://localhost/MVCAPI/api/values/GetDispatchData
- まだダメなら IIS ログとハンドラー マッピングを確認
- 404.2 / 404.3 なら ASP.NET 機能やハンドラー設定が怪しい
- ExtensionlessUrlHandler-Integrated-4.0 の有無をチェック
この手順を一つずつ潰していけば、「IIS Express では動くのに IIS では 404」という典型的な問題はほぼ必ず解消できます。特に、ソースの手動コピーではなく発行を使うことと、Windows 機能とアプリケーション プールを正しく揃えることが最大のポイントです。

コメント