次の方法で共有


Visual Studio で動作し、運用 IIS サーバーで失敗する Web API2 アプリのトラブルシューティング

このドキュメントでは、運用 IIS サーバーに配置されている Web API2 アプリのトラブルシューティング方法について説明します。 一般的な HTTP 405 および 501 エラーに対処します。

このチュートリアルで使用されるソフトウェア

Web API アプリでは、通常、いくつかの HTTP 動詞 (GET、POST、PUT、DELETE、場合によっては PATCH) が使用されます。 つまり、開発者は、これらの動詞が運用 IIS サーバー上の別の IIS モジュールによって実装される状況を経験する可能性があります。これにより、Visual Studio または開発サーバーで正常に動作する Web API コントローラーが運用 IIS サーバーに展開されると、HTTP 405 エラーが返される状況が発生する可能性があります。

HTTP 405 エラーの原因

HTTP 405 エラーのトラブルシューティングを行う方法を学習するための最初の手順は、HTTP 405 エラーが実際に何を意味するかを理解することです。 HTTP の主要な管理ドキュメントは RFC 2616 で、HTTP 405 状態コードを "メソッドは許可されていません" として定義しています。さらに、この状態コードは、"Request-Line で指定されたメソッドは、Request-URI で識別されるリソースでは許可されていません" という状況として記述されています。つまり、HTTP クライアントから要求した特定の URL に対して HTTP 動詞を使用することはできません。

簡単なレビューとして、RFC 2616、RFC 4918、RFC 5789 で定義されている最もよく使用される HTTP メソッドをいくつか次に示します。

HTTP メソッド 説明
GET このメソッドは URI からデータを取得するために使用され、おそらく最も使用される HTTP メソッドです。
HEAD このメソッドは GET メソッドとよく似ていますが、実際には要求 URI からデータを取得しません。HTTP 状態を取得するだけです。
投稿 このメソッドは、通常、URI に新しいデータを送信するために使用されます。POST は多くの場合、フォーム データを送信するために使用されます。
PUT このメソッドは、通常、生データを URI に送信するために使用されます。PUT は、JSON または XML データを Web API アプリケーションに送信するためによく使用されます。
DELETE このメソッドは、URI からデータを削除するために使用されます。
[オプション (オプション)] このメソッドは、通常、URI でサポートされている HTTP メソッドの一覧を取得するために使用されます。
COPY MOVE これら 2 つのメソッドは WebDAV と共に使用され、その目的は自明です。
MKCOL このメソッドは WebDAV と共に使用され、指定された URI でコレクション (ディレクトリなど) を作成するために使用されます。
PROPFIND PROPPATCH これら 2 つのメソッドは WebDAV と共に使用され、URI のプロパティのクエリ実行または設定に使用されます。
LOCK UNLOCK これら 2 つのメソッドは WebDAV と共に使用され、作成時に要求 URI によって識別されるリソースをロック/ロック解除するために使用されます。
PATCH このメソッドは、既存の HTTP リソースを変更するために使用されます。

これらの HTTP メソッドのいずれかがサーバーで使用されるように構成されている場合、サーバーでは、HTTP 状態と、要求に適したその他のデータで応答します。 (たとえば、GET メソッドでは HTTP 200 OK 応答を受け取る場合があります。PUT メソッドでは HTTP 201 "作成されました" 応答を受け取る場合があります)。

HTTP メソッドがサーバーで使用するように構成されていない場合、サーバーは HTTP 501 "実装されていません" エラーで応答します。

ただし、HTTP メソッドがサーバーで使用するように構成されているが、特定の URI に対して無効になっている場合、サーバーでは HTTP 405 "メソッドは許可されていません" エラーで応答します。

HTTP 405 エラーの例

次の HTTP 要求と応答の例は、HTTP クライアントによって Web サーバー上の Web API アプリに値を PUT しようとしたときに、PUT メソッドが許可されていないことを示す HTTP エラーがサーバーによって返される状況を示しています。

HTTP 要求:

PUT /api/values/1 HTTP/1.1
Content-type: application/json
Host: localhost
Accept: */*
Content-Length: 12

"Some Value"

HTTP 応答:

HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET
Date: Wed, 15 May 2013 02:38:57 GMT
Content-Length: 72

{"Message":"The requested resource does not support http method 'PUT'."}

この例では、HTTP クライアントから Web サーバー上の Web API アプリケーションの URL に有効な JSON 要求を送信しましたが、サーバーでは、URL に対して PUT メソッドが許可されていないことを示す HTTP 405 エラー メッセージを返しました。 これに対し、要求 URI が Web API アプリケーションのルートと一致しない場合、サーバーでは HTTP 404 "見つかりません" エラーを返します。

HTTP 405 エラーを解決する

特定の HTTP 動詞が許可されない理由はいくつかありますが、IIS でこのエラーの主な原因となる主なシナリオが 1 つあります。複数のハンドラーが同じ動詞/メソッドに対して定義されており、ハンドラーの 1 つによって、予期されるハンドラーによる要求の処理がブロックされています。 説明として、IIS では、applicationHost.config および web.config ファイル内の順序ハンドラー エントリに基づいて全部のハンドラーを処理します。ここで、要求を処理するために、パス、動詞、リソースなどの最初の一致の組み合わせが使用されます。

次の例は、PUT メソッドを使用して Web API アプリケーションにデータを送信するときに HTTP 405 エラーを返していた、IIS サーバーの applicationHost.config ファイルからの抜粋です。 この抜粋では、いくつかの HTTP ハンドラーが定義されており、各ハンドラーには、これが構成されている対象の HTTP メソッドの異なるセットがあります。リスト内の最後のエントリは静的コンテンツ ハンドラーであり、他のハンドラーで要求を調べることができた後で使用される既定のハンドラーです。

<handlers accessPolicy="Read, Script">
   <add name="WebDAV"
      path="*"
      verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK"
      modules="WebDAVModule"
      resourceType="Unspecified"
      requireAccess="None" />
   <add name="ISAPI-dll"
      path="*.dll"
      verb="*"
      modules="IsapiModule"
      resourceType="File"
      requireAccess="Execute"
      allowPathInfo="true" />
   <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"
      path="*."
      verb="GET,HEAD,POST,DEBUG"
      modules="IsapiModule"
      scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
      preCondition="classicMode,runtimeVersionv4.0,bitness64"
      responseBufferLimit="0" />

   <!-- Additional handlers will be defined here. -->

   <add name="StaticFile"
      path="*"
      verb="*"
      modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule"
      resourceType="Either"
      requireAccess="Read" />
</handlers>

前の例では、HTTP メソッドの個別のリストに対して、WebDAV ハンドラーと ASP.NET 用の拡張子のない URL ハンドラー (Web API に使用されます) が明確に定義されています。 ISAPI DLL ハンドラーはすべての HTTP メソッドに対して構成されますが、この構成では必ずしもエラーが発生するとは限らないことに注意してください。 ただし、HTTP 405 エラーのトラブルシューティングを行うときは、このような構成設定を考慮する必要があります。

前の例では、ISAPI DLL ハンドラーは問題になりませんでした。実際、この問題は IIS サーバーの applicationHost.config ファイルで定義されていませんでした。この問題は、Web API アプリケーションが Visual Studio で作成されたときに web.config ファイルで作成されたエントリによって発生しました。 アプリケーションの web.config ファイルからの次の抜粋は、問題の場所を示しています。

<handlers accessPolicy="Read, Script">
   <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
   <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"
      path="*."
      verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
      modules="IsapiModule"
      scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
      preCondition="classicMode,runtimeVersionv4.0,bitness64"
      responseBufferLimit="0" />
</handlers>

この抜粋では、Web API アプリケーションで使用される追加の HTTP メソッドが含まれるように、ASP.NET の拡張子のない URL ハンドラーが再定義されています。 ただし、WebDAV ハンドラーに対して同様の HTTP メソッドのセットが定義されているため、競合が発生します。 この特定のケースでは、Web API アプリケーションを含む Web サイトに対して WebDAV が無効になっている場合でも、WebDAV ハンドラーは IIS によって定義されて読み込まれます。 HTTP PUT 要求の処理中、IIS は PUT 動詞に対して定義されているため、WebDAV モジュールを呼び出します。 WebDAV モジュールが呼び出されると、その構成がチェックされ、無効になっていることがわかります。そのため、WebDAV 要求に似た要求に対して HTTP 405 "メソッドは許可されていません" エラーが返されます。 この問題を解決するには、Web API アプリケーションが定義されている Web サイトの HTTP モジュールの一覧から WebDAV を削除する必要があります。 次の例は、これがどのようになるかを示しています。

<handlers accessPolicy="Read, Script">
   <remove name="WebDAV" />
   <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
   <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"
      path="*."
      verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
      modules="IsapiModule"
      scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
      preCondition="classicMode,runtimeVersionv4.0,bitness64"
      responseBufferLimit="0" />
</handlers>

このシナリオは、開発環境から IIS 運用環境にアプリケーションを発行した後によく発生します。これは、ハンドラー/モジュールの一覧が開発と運用環境で異なるために発生します。 たとえば、Visual Studio 2012 以降を使用して Web API アプリケーションを開発する場合、IIS Express はテスト用の既定の Web サーバーです。 この開発 Web サーバーは、サーバー製品に付属する完全な IIS 機能のスケールダウン バージョンであり、この開発 Web サーバーには、開発シナリオ用に追加されたいくつかの変更が含まれています。 たとえば、WebDAV モジュールは、通常、IIS のフル バージョンを実行している運用 Web サーバーにインストールされますが、使用されていない可能性があります。 IIS の開発バージョン (IIS Express) では、WebDAV モジュールをインストールしますが、WebDAV モジュールのエントリは意図的にコメント アウトされるため、IIS Express の構成設定を特に変更して IIS Express のインストールに WebDAV 機能を追加しない限り、WebDAV モジュールは IIS Express に読み込まれません。 その結果、開発用コンピューターで Web アプリケーションが正常に動作する可能性がありますが、Web API アプリケーションを運用 IIS Web サーバーに発行すると、HTTP 405 エラーが発生する可能性があります。

HTTP 501 エラー

  • 特定の機能がサーバーに実装されていないことを示します。
  • 通常は、HTTP 要求に一致するハンドラーが IIS 設定に定義されていないことを意味します。
    • IIS に何かが正しくインストールされていないことを示している可能性があります。または
    • 何かによって IIS の設定が変更されたため、特定の HTTP メソッドをサポートするハンドラーが定義されていません。

この問題を解決するには、対応するモジュールまたはハンドラー定義がない HTTP メソッドを使用しようとしているアプリケーションを再インストールする必要があります。

まとめ

HTTP 405 エラーは、要求された URL に対して Web サーバーによって HTTP メソッドが許可されていない場合に発生します。 この条件は、特定の動詞に対して特定のハンドラーが定義されていて、そのハンドラーによって、要求を処理させるハンドラーがオーバーライドされている場合によく見られます。