到的ASP.NET Web API的所有请求返回404错误 [英] All requests to ASP.NET Web API return 404 error

查看:1614
本文介绍了到的ASP.NET Web API的所有请求返回404错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASP.NET MVC 4的网站,包括网站的API。该网站的开发和使用的Visual Studio 2012和.NET 4.5在Windows 8上使用IIS防爆preSS作为Web服务器进行测试。 在这个开发环境中一切正常。

现在它被部署在Windows 2008 R2(SP1)服务器与IIS 7.5上。 .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,以及与消息:

  

没有HTTP资源被发现,相匹配的请求URI

我创建了一个测试网站,MVC 4和Web API,以及和它部署在同一台服务器和Web API的作品上。网络API和MVC组件有两个相同的版本号项目。

此外,我已经添加了<一href="http://blogs.msdn.com/b/webdev/archive/2013/04/04/debugging-asp-net-web-api-with-route-debugger.aspx">Web API路线调试的应用程序。如果我使用像一个有效途径的http:// MYSERVER / API /顺序/ 12 我得到以下结果:

对于我来说,这意味着正确的路径模板 API / {控制器} / {ID} 已发现并正确解析成一个控制器订单 n = 12 。控制器(从 ApiController 导出)存在于网络组件,其中也都MVC控制器。

不过,我不知道是什么状态 000 可能意味着,为什么没有路径选择一节中显示(这是通常的情况即使装配不包含一个 ApiController ,见链接页面上的截图以上)。不知怎的,它看起来像没有 ApiController 被发现,甚至没有搜索或搜索失败默默地。

IIS日志文件中不显示任何用处。改变各种应用程序池设置,并使用相同的应用程序池的试验和实际应用并没有帮助。

我目前在这个过程中,从应用程序中删除功能,配置设置,第三方组件等使其下降到最终的测试应用程序的体积小,希望在某个时候开始工作

是否有人有什么线索,这个问题可能是什么?同时,任何调试或记录想法可能找到原因很欢迎的。

修改

由于达雷尔 - 米勒的提示在下面的评论我已经整合的用于跟踪的ASP.NET Web阿比

有关的(GET)请求的URL 的http:// MYSERVER / API /顺序/ 12 我得到了以下内容:

  • 在开发环境中,成功的(缩略形式):
  

消息:的http://本地主机:50020 / API /顺序/ 12 ;类别:   System.Web.Http.Request

     

控制器的选择和实例...

     

运营商:DefaultHttpControllerSelector;操作:SelectController;   消息:路径=控制器:顺序,编号: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;操作:协商;消息:典型​​值=字符串...   更多

     

处置控制器...

     

运营商:OrderController;操作:处置;信息: ;类别:   System.Web.Http.Controllers

  • 在生产环境中,没有成功(缩略形式):
  

消息:的http:// MYSERVER / API /顺序/ 12 ;类别:   System.Web.Http.Request

     

运营商:DefaultHttpControllerSelector;操作:SelectController;   消息:路径=控制器:顺序,编号:12;类别:   System.Web.Http.Controllers

     

控制器激活,行动选择,整体的一部分参数绑定,调用行动失踪,它遵循的内容   谈判和格式的错误信息立即

     

运营商:DefaultContentNegotiator;操作:协商;信息:   TYPE =HTTPError这样的...的更多

解决方案

由于基兰Challa 的意见和源从这个答案我能弄清楚,一个汇编(的ReportViewer 11组装为SQL Server报表服务)缺少生产服务器上。

虽然没有 ApiController 是本次大会似乎会导致控制器的组件 - 在这种情况下,我的Web项目的组件 - 被引用丢失的组件都没有发现。

显然,这种行为是与这片code从<一个href="http://aspnetwebstack.$c$cplex.com/SourceControl/latest#src/System.Web.Http/Dispatcher/DefaultHttpControllerTypeResolver.cs">Web API的 DefaultHttpControllerTypeResolver 来源:

 名单,其中,类型和GT;结果=新名单,其中,类型和GT;();

//遍历由应用程序引用的所有程序集
//并搜索类型匹配predicate
ICollection的&LT;大会&GT;组件= assembliesResolver.GetAssemblies();
的foreach(在组件装配组装)
{
    键入[] exportedTypes = NULL;
    如果(组装== NULL || assembly.IsDynamic)
    {
        //不能叫GetExportedTypes在动态程序集
        继续;
    }

    尝试
    {
        exportedTypes = assembly.GetExportedTypes();
    }
    赶上(ReflectionTypeLoadException前)
    {
        exportedTypes = ex.Types;
    }
    抓住
    {
        构建缓存时,//我们故意忽略所有异常。如果
        //控制器的类型没有找到那么我们会在以后使用404回应。
        //然而,在此之前,我们不知道是否异常都将
        //必须找到一个控制器产生影响。
        继续;
    }

    如果(exportedTypes!= NULL)
    {
        result.AddRange(exportedTypes.Where(X =&GT; IsControllerType predicate(X)));
    }
}
 

我不知道,如果它必须是这样的,我不是通过在code中的注释,但这个抓很相信...继续块是相当沉默可能出现的问题和我花了大量的时间和精力来找到它。我甚至知道了的ReportViewer 是尚未安装。我试图安装它,依赖程序集,但它阻止了服务器上的其他正在运行的进程,所以我决定推迟安装,直到我可以联系管理员,专注于MVC和的WebAPI测试第一 - 大错!如果没有基兰的调试code段我从未有过的想法,存在一个 ReportViewer.dll 能有什么关系控制器类型解析。

在我看来还有改进的空间对于一般的开发商像我这样谁没有关于网络API的内部工作有较深造诣。

在安装后失踪 ReportViewer.dll 问题就消失了。

下面是差不多的症状,其中的的问题可能有的同样的原因:

  • 所有的ASP.NET Web API控制器返回404
  • <一个href="http://stackoverflow.com/questions/16192445/net-web-api-no-http-resource-was-found-that-matches-the-request-uri">.Net网络API没有HTTP资源发现,请求URI
  • 匹配
  • <一个href="http://forums.asp.net/t/1861082.aspx/1?All+controllers+break+404+whenever+I+publish+to+Azure">http://forums.asp.net/t/1861082.aspx/1?All+controllers+break+404+whenever+I+publish+to+Azure

修改

我已经发布了关于提高codePLEX一个请求:

<一个href="http://aspnetwebstack.$c$cplex.com/workitem/1075">http://aspnetwebstack.$c$cplex.com/workitem/1075

修改2(8月11日'13)

这个问题已经被固定的WebAPI V5.0 RC。请参阅上面的工作项目和细节的评论部分中的链接。

I have an ASP.NET MVC 4 web site that includes Web API. The site is developed and tested with Visual Studio 2012 and .NET 4.5 on Windows 8 with IIS Express as web server. In this development environment everything works.

Now it is deployed on a Windows 2008 R2 (SP1) Server with IIS 7.5. .NET 4.0 and 4.5 are installed. The application pool is running with .NET 4.0 in integrated pipeline mode.

In this production environment the MVC web site works, Web API does not. For every request, no matter if GET or POST I get a 404 error. If I just enter a Web API Url in the browser (IE 9 opened locally on the server) to run a GET request I get a 404 page. If I issue a POST request from a Web API client application I get a 404 as well and the message:

No HTTP resource was found that matches the request URI

I've created a test website with MVC 4 and Web API as well and deployed it on the same server and the Web API works. Web API and MVC assemblies have the same version number in both projects.

Furthermore I have added the Web API Route Debugger to the application. If I use a valid route like http://myserver/api/order/12 I get the following result:

For me this means that the correct route template Api/{Controller}/{Id} has been found and correctly parsed into a controller Order and Id=12. The controller (derived from ApiController) exists in the web assembly where also all MVC controllers are.

However, I don't know what the status 000 could mean and why there is no "Route selecting" section displayed (which is normally the case even if the assembly doesn't contain a single ApiController, see screenshots on the linked page above). Somehow it looks like no ApiController is found or even not searched for or the search fails silently.

The IIS log files don't show anything useful. Changing various application pool settings and using the same app pool for the test and the real application didn't help.

I am currently in the process to remove "features", configuration settings, third party assemblies, etc. from the application to bring it down to the small size of the test application in the end and hoping that at some point it starts to work.

Does somebody have a clue what the issue could be? Also any debugging or logging idea to possibly find the reason is very welcome.

Edit

Thanks to Darrel Miller's tip in the comments below I have integrated Tracing for ASP.NET Web Api.

For the (GET) request URL http://myserver/api/order/12 I get the following:

  • In development environment, successful (in short form):

Message: http://localhost:50020/api/order/12; Category: System.Web.Http.Request

Controller selection and instantiation...

Operator: DefaultHttpControllerSelector; Operation: SelectController; Message: Route="controller:order,id:12"; Category: System.Web.Http.Controllers

Operator: DefaultHttpControllerSelector; Operation: SelectController; Message: Order; Category: System.Web.Http.Controllers

Operator: HttpControllerDescriptor; Operation: CreateController; Message: ; Category: System.Web.Http.Controllers

Operator: DefaultHttpControllerActivator; Operation: Create; Message: ; Category: System.Web.Http.Controllers

Operator: DefaultHttpControllerActivator; Operation: Create; Message: MyApplication.ApiControllers.OrderController; Category: System.Web.Http.Controllers

Action selection, parameter binding and action invocation follows...

Content negotiation and formatting for result...

Operator: DefaultContentNegotiator; Operation: Negotiate; Message: Typ = "String" ... more

Disposing the controller...

Operator: OrderController; Operation: Dispose; Message: ; Category: System.Web.Http.Controllers

  • In production environment, not successful (in short form):

Message: http://myserver/api/order/12; Category: System.Web.Http.Request

Operator: DefaultHttpControllerSelector; Operation: SelectController; Message: Route="controller:order,id:12"; Category: System.Web.Http.Controllers

The whole part of controller activation, action selection, parameter binding, action invocation is missing and it follows content negotiation and formatting for the error message immediately:

Operator: DefaultContentNegotiator; Operation: Negotiate; Message: Type = "HttpError" ... more

解决方案

Thanks to Kiran Challa's comment and source code from this answer I was able to figure out that an assembly (the ReportViewer 11 assembly for SQL Server Reporting Services) was missing on the production server.

Although no ApiController is in this assembly it seems to cause that controllers in assemblies - in this case my Web project's assembly - that are referencing the missing assembly are not found.

Apparently this behaviour is related to this piece of code from the Web API's DefaultHttpControllerTypeResolver source:

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)));
    }
}

I don't know if it has to be this way and I am not quite convinced by the comment in the code but this catch ... continue block is rather silent about a possible problem and it took me a huge amount of time and frustration to find it. I even knew that the ReportViewer wasn't installed yet. I tried to install it and dependent assemblies but it was blocked by another running process on the server, so I decided to postpone the installation until I could contact the administrator and focus on MVC and WebAPI testing first - big mistake! Without Kiran's debugging code snippet I had never had the idea that the existence of a ReportViewer.dll could have anything to do with controller type resolution.

In my opinion there is room for improvement for the average developer like me who doesn't have a deeper knowledge about the inner workings of Web API.

After installing the missing ReportViewer.dll the problem disappeared.

Here are questions about the same symptom which might have the same reason:

Edit

I have issued a request for improvement on CodePlex:

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

Edit 2 (Aug 11 '13)

The issue has been fixed for WebAPI v5.0 RC. See the link above to the workitem and its comments section for details.

这篇关于到的ASP.NET Web API的所有请求返回404错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆