webdevqa.jp.net

ASP.NET Web APIへのすべてのリクエストが404エラーを返す

Web APIを含むASP.NET MVC 4 Webサイトがあります。このサイトは、WebサーバーとしてIIS Expressを使用して、Windows 8上のVisual Studio 2012および.NET 4.5で開発およびテストされています。 この開発環境ではすべてが機能します。

現在は、IIS 7.5を備えたWindows 2008 R2(SP1)サーバーに展開されています。 .NET 4.0および4.5がインストールされます。アプリケーションプールは、統合パイプラインモードの.NET 4.0で実行されています。

この実稼働環境では、MVC Webサイトは機能しますが、Web APIは機能しません。GETまたはPOSTに関係なく、リクエストごとに404エラーが発生します。ブラウザーにWeb API Urlを入力して(IE 9がサーバー上でローカルに開かれた)GETリクエストを実行すると、404ページが表示されます。 Web APIクライアントアプリケーションからPOSTリクエストを発行すると、404とメッセージも取得されます。

要求URIに一致するHTTPリソースが見つかりませんでした

MVC 4とWeb APIを使用してテストWebサイトを作成し、同じサーバーに展開し、Web APIが機能します。Web APIとMVCアセンブリのバージョン番号は同じです両方のプロジェクトで。

さらに、アプリケーションに Web API Route Debugger を追加しました。 http://myserver/api/order/12のような有効なルートを使用すると、次の結果が得られます。

Route Debugger

私にとってこれは、正しいルートテンプレートApi/{Controller}/{Id}が見つかり、コントローラーOrderおよびId=12に正しく解析されたことを意味します。コントローラー(ApiControllerから派生)は、すべてのMVCコントローラーがあるWebアセンブリに存在します。

ただし、ステータス000の意味と、表示される[ルート選択]セクションがない理由はわかりません(通常、アセンブリに単一のApiControllerが含まれていない場合でも、上記のリンク先ページのスクリーンショットをご覧ください)。どういうわけかApiControllerが見つからないか、検索されていないか、サイレントに検索が失敗しているように見えます。

IISログファイルには、有用なものは何も表示されません。さまざまなアプリケーションプールの設定を変更し、テストと実際のアプリケーションに同じアプリケーションプールを使用しても役に立ちませんでした。

現在、アプリケーションから「機能」、構成設定、サードパーティアセンブリなどを削除して、最終的にテストアプリケーションのサイズを小さくし、ある時点で動作を開始することを望んでいます。

誰かが問題が何であるかの手がかりを持っていますか?また、理由を見つけるためのデバッグやロギングのアイデアも大歓迎です。

編集

下のコメントにあるDarrel Millerのヒントのおかげで、 Tracing for ASP.NET Web Api と統合しました。

(GET)リクエストURL http://myserver/api/order/12の場合、次のようになります。

  • 開発環境で成功(短い形式で):

メッセージ:http://localhost:50020/api/order/12;カテゴリ:System.Web.Http.Request

コントローラーの選択とインスタンス化...

演算子:DefaultHttpControllerSelector;操作:SelectController;メッセージ:Route = "controller:order、id:12";カテゴリ:System.Web.Http.Controllers

演算子:DefaultHttpControllerSelector;操作:SelectController;メッセージ:注文;カテゴリ:System.Web.Http.Controllers

演算子:HttpControllerDescriptor;操作:CreateController;メッセージ:;カテゴリ:System.Web.Http.Controllers

オペレーター:DefaultHttpControllerActivator;操作:作成;メッセージ:;カテゴリ:System.Web.Http.Controllers

オペレーター:DefaultHttpControllerActivator;操作:作成;メッセージ:MyApplication.ApiControllers.OrderController;カテゴリ:System.Web.Http.Controllers

アクションの選択、パラメーターのバインド、アクションの呼び出しが続きます...

コンテンツのネゴシエーションと結果のフォーマット...

演算子:DefaultContentNegotiator;操作:交渉。メッセージ:Typ = "String" ... more

コントローラーの廃棄...

オペレーター:OrderController;操作:廃棄;メッセージ:;カテゴリ:System.Web.Http.Controllers

  • 実稼働環境では、成功しません(短い形式):

メッセージ:http://myserver/api/order/12;カテゴリ:System.Web.Http.Request

演算子:DefaultHttpControllerSelector;操作:SelectController;メッセージ:Route = "controller:order、id:12";カテゴリ:System.Web.Http.Controllers

コントローラーのアクティブ化、アクション選択、パラメーターバインディング、アクション呼び出しのすべての部分が欠落しており、コンテンツネゴシエーションとエラーメッセージのフォーマットに従います

演算子:DefaultContentNegotiator;操作:交渉。メッセージ:タイプ= "HttpError" ... more

29
Slauma

Kiran Challa's からのコメントとソースコード この回答 のおかげで、アセンブリ(SQL Server Reporting ServicesのReportViewer 11 Assembly)が欠落していることがわかりました。実動サーバー。

このアセンブリにはApiControllerはありませんが、アセンブリ内のコントローラー(この場合は、私のWebプロジェクトのアセンブリ)に、欠落しているアセンブリを参照しているコントローラーが見つからないようです。

どうやらこの動作は Web APIのDefaultHttpControllerTypeResolver ソースからのこのコードに関連しているようです:

List<Type> result = new List<Type>();

// Go through all assemblies referenced by the application
// and search for types matching a predicate
ICollection<Assembly> assemblies = assembliesResolver.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
    Type[] exportedTypes = null;
    if (Assembly == null || Assembly.IsDynamic)
    {
        // can't call GetExportedTypes on a dynamic Assembly
        continue;
    }

    try
    {
        exportedTypes = Assembly.GetExportedTypes();
    }
    catch (ReflectionTypeLoadException ex)
    {
        exportedTypes = ex.Types;
    }
    catch
    {
        // We deliberately ignore all exceptions when building the cache. If 
        // a controller type is not found then we will respond later with a 404.
        // However, until then we don't know whether an exception at all will
        // have an impact on finding a controller.
        continue;
    }

    if (exportedTypes != null)
    {
        result.AddRange(exportedTypes.Where(x => IsControllerTypePredicate(x)));
    }
}

このようにする必要があるかどうかはわかりませんが、コード内のコメントには納得できませんが、このcatch ... continueブロックは問題の可能性については静かであり、膨大な時間とフラストレーションがかかりましたそれを見つけるために。 ReportViewerがまだインストールされていないことも知っていました。私はそれと依存アセンブリをインストールしようとしましたが、サーバー上で別の実行中のプロセスによってブロックされたため、管理者に連絡してMVCとWebAPIのテストに集中できるようになるまでインストールを延期することに決めました-大きな間違い! Kiranのデバッグコードスニペットがなければ、ReportViewer.dllの存在がコントローラーの型解決と関係があるとは思いもしませんでした。

私の意見では、Web APIの内部動作に関する深い知識を持っていない私のような平均的な開発者には改善の余地があります。

不足しているReportViewer.dllをインストールすると、問題はなくなりました。

同じ理由がある可能性がある同じ症状に関する質問を次に示します。

編集

CodePlexの改善要求を発行しました。

http://aspnetwebstack.codeplex.com/workitem/1075

Edit 2(13年8月11日)

この問題はWebAPI v5.0 RCで修正されました。詳細については、上記のワークアイテムとそのコメントセクションへのリンクを参照してください。

23
Slauma

この回答の素晴らしいリソース、しかし、私はかなり愚かな理由であることが判明したために404を取得していました:

  1. APIプロジェクトのWiXインストーラーを作成しました
  2. テストにインストールしましたVM(仮想マシン)
  3. APIが提供するURIを要求しました
  4. バン! 404 :(

パッケージングとGlobal.asaxをパッケージ化して展開中の仮想ディレクトリのルートに展開できなかったことが判明しました。私のような間抜けな人のためにこれをここに追加します:)

5

リモートサーバーでも同じ問題が発生しましたが、ローカルホストで実行すると問題なく動作します。

私の解決策は:

<system.webServer>
    <modules>
        <remove name="UrlRoutingModule-4.0" />
        <add name="UrlRoutingModule-4.0" 
            type="System.Web.Routing.UrlRoutingModule" preCondition="" /> 
    </modules>
</system.webServer>

これがあなたの役に立つことを願っています。

0
framled