Asp.net

對 ASP.NET Web API 的所有請求都返回 404 錯誤

  • May 29, 2013

我有一個包含 Web API 的 ASP.NET MVC 4 網站。該站點是在 Windows 8 上使用 Visual Studio 2012 和 .NET 4.5 開發和測試的,IIS Express 作為 Web 伺服器。在這個開發環境中一切正常。

現在它部署在帶有 IIS 7.5 的 Windows 2008 R2 (SP1) 伺服器上。.NET 4.0 和 4.5 已安裝。應用程序池在集成管道模式下使用 .NET 4.0 執行。

**在這個生產環境中,MVC 網站工作,Web API 不工作。**對於每個請求,無論是 GET 還是 POST,我都會收到 404 錯誤。如果我只是在瀏覽器中輸入一個 Web API Url(在伺服器上本地打開 IE 9)來執行一個 GET 請求,我會得到一個 404 頁面。如果我從 Web API 客戶端應用程序發出 POST 請求,我也會收到 404 和以下消息:

未找到與請求 URI 匹配的 HTTP 資源

**我還使用 MVC 4 和 Web API 創建了一個測試網站,並將其部署在同一台伺服器上,並且 Web API 可以正常工作。**Web API 和 MVC 程序集在兩個項目中具有相同的版本號。

此外,我已將Web API 路由調試器添加到應用程序中。如果我使用像http://myserver/api/order/12我這樣的有效路線,則會得到以下結果:

路由調試器

對我來說,這意味著Api/{Controller}/{Id}已找到正確的路由模板並將其正確解析為控制器OrderId=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;操作:選擇控制器;消息:Route=“controller:order,id:12”; 類別:System.Web.Http.Controllers

運算符:DefaultHttpControllerSelector;操作:選擇控制器;消息:訂單;類別:System.Web.Http.Controllers

運算符:HttpControllerDescriptor;操作:創建控制器;資訊: ; 類別:System.Web.Http.Controllers

運算符:DefaultHttpControllerActivator;操作:創建;資訊: ; 類別:System.Web.Http.Controllers

運算符:DefaultHttpControllerActivator;操作:創建;消息:MyApplication.ApiControllers.OrderController;類別:System.Web.Http.Controllers

動作選擇、參數綁定和動作呼叫如下…

結果的內容協商和格式化…

運算符:DefaultContentNegotiator;操作:協商;消息:Typ = “String” … 更多

處理控制器…

操作員:訂單控制器;操作:處置;資訊: ; 類別:System.Web.Http.Controllers

  • 在生產環境中,不成功(簡稱):

留言:http://myserver/api/order/12; 類別:System.Web.Http.Request

運算符:DefaultHttpControllerSelector;操作:選擇控制器;消息:Route=“controller:order,id:12”; 類別:System.Web.Http.Controllers

控制器啟動、動作選擇、參數綁定、動作呼叫的整個部分都失去了,它立即遵循錯誤消息的內容協商和格式化

運算符:DefaultContentNegotiator;操作:協商;消息:Type = “HttpError” …更多

感謝Kiran Challa 的評論和來自這個答案的原始碼,我能夠弄清楚ReportViewer 11 assembly生產伺服器上缺少一個程序集(用於 SQL Server Reporting Services)。

儘管ApiController此程序集中沒有,但它似乎導致程序集中的控制器(在本例中為我的 Web 項目的程序集)正在引用缺少的程序集。

顯然,此行為與Web APIDefaultHttpControllerTypeResolver源中的這段程式碼有關:

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 的調試程式碼片段,我從未想過 a 的存在ReportViewer.dll可能與控制器類型解析有關。

在我看來,對於像我這樣對 Web API 的內部工作沒有更深入了解的普通開發人員來說,還有改進的空間。

安裝後失去ReportViewer.dll的問題消失了。

以下是關於可能具有相同原因的相同症狀的問題:

編輯

我已發出對 CodePlex 的改進請求:

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

編輯 2(2013 年 8 月 11 日)

該問題已針對 WebAPI v5.0 RC 進行了修復。有關詳細資訊,請參閱上面指向工作項及其評論部分的連結。

引用自:https://stackoverflow.com/questions/16812995