简体   繁体   English

对ASP.NET Web API的所有请求都返回404错误

[英]All requests to ASP.NET Web API return 404 error

I have an ASP.NET MVC 4 web site that includes Web API. 我有一个包含Web API的ASP.NET MVC 4网站。 The site is developed and tested with Visual Studio 2012 and .NET 4.5 on Windows 8 with IIS Express as web server. 该站点在Windows 8上使用Visual Studio 2012和.NET 4.5进行开发和测试,其中IIS Express作为Web服务器。 In this development environment everything works. 在这个开发环境中一切正常。

Now it is deployed on a Windows 2008 R2 (SP1) Server with IIS 7.5. 现在它部署在带有IIS 7.5的Windows 2008 R2(SP1)服务器上。 .NET 4.0 and 4.5 are installed. 安装了.NET 4.0和4.5。 The application pool is running with .NET 4.0 in integrated pipeline mode. 应用程序池在.NET 4.0中以集成管道模式运行。

In this production environment the MVC web site works, Web API does not. 在这个生产环境中,MVC网站可以正常工作,而Web API却没有。 For every request, no matter if GET or POST I get a 404 error. 对于每个请求,无论GET还是POST,我都会收到404错误。 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. 如果我只是在浏览器中输入Web API Url(在服务器上本地打开IE 9)来运行GET请求,我会得到一个404页面。 If I issue a POST request from a Web API client application I get a 404 as well and the message: 如果我从Web API客户端应用程序发出POST请求,我也会收到404消息:

No HTTP resource was found that matches the request URI 未找到与请求URI匹配的HTTP资源

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. 我已经创建了一个带有MVC 4和Web API的测试网站,并将其部署在同一台服务器上并且Web API正常工作。 Web API and MVC assemblies have the same version number in both projects. Web API和MVC程序集在两个项目中具有相同的版本号。

Furthermore I have added the Web API Route Debugger to the application. 此外,我已将Web API Route Debugger添加到应用程序中。 If I use a valid route like http://myserver/api/order/12 I get the following result: 如果我使用http://myserver/api/order/12这样的有效路由,我会得到以下结果:

路由调试器

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 . 对我来说,这意味着找到了正确的路径模板Api/{Controller}/{Id}并将其正确解析为控制器OrderId=12 The controller (derived from ApiController ) exists in the web assembly where also all MVC controllers are. 控制器(派生自ApiController )存在于Web程序集中,其中所有MVC控制器也是如此。

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). 但是,我不知道状态000可能意味着什么以及为什么没有显示“ ApiController选择”部分(通常情况下,即使程序集不包含单个ApiController ,请参见上面链接页面上的屏幕截图) 。 Somehow it looks like no ApiController is found or even not searched for or the search fails silently. 不知怎的,它看起来没有找到甚至没有找到ApiController ,或者搜索失败了。

The IIS log files don't show anything useful. IIS日志文件没有显示任何有用的内容。 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 . 感谢Darrel Miller在下面评论中的提示,我已经集成了针对ASP.NET Web Api的跟踪

For the (GET) request URL http://myserver/api/order/12 I get the following: 对于(GET)请求URL http://myserver/api/order/12我得到以下内容:

  • In development environment, successful (in short form): 在开发环境中,成功 (简短形式):

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

Controller selection and instantiation... 控制器选择和实例化......

Operator: DefaultHttpControllerSelector; 运算符:DefaultHttpControllerSelector; Operation: SelectController; 操作:SelectController; Message: Route="controller:order,id:12"; 消息:Route =“controller:order,id:12”; Category: System.Web.Http.Controllers 类别:System.Web.Http.Controllers

Operator: DefaultHttpControllerSelector; 运算符:DefaultHttpControllerSelector; Operation: SelectController; 操作:SelectController; Message: Order; 消息:订单; Category: System.Web.Http.Controllers 类别:System.Web.Http.Controllers

Operator: HttpControllerDescriptor; 运算符:HttpControllerDescriptor; Operation: CreateController; 操作:CreateController; Message: ; 信息: ; Category: System.Web.Http.Controllers 类别:System.Web.Http.Controllers

Operator: DefaultHttpControllerActivator; 运算符:DefaultHttpControllerActivator; Operation: Create; 操作:创建; Message: ; 信息: ; Category: System.Web.Http.Controllers 类别:System.Web.Http.Controllers

Operator: DefaultHttpControllerActivator; 运算符:DefaultHttpControllerActivator; Operation: Create; 操作:创建; Message: MyApplication.ApiControllers.OrderController; 消息:MyApplication.ApiControllers.OrderController; Category: System.Web.Http.Controllers 类别:System.Web.Http.Controllers

Action selection, parameter binding and action invocation follows... 动作选择,参数绑定和动作调用如下......

Content negotiation and formatting for result... 内容协商和格式化结果......

Operator: DefaultContentNegotiator; 运算符:DefaultContentNegotiator; Operation: Negotiate; 操作:谈判; Message: Typ = "String" ... more 消息:Typ =“String”... 更多

Disposing the controller... 处理控制器......

Operator: OrderController; 运算符:OrderController; Operation: Dispose; 操作:处理; Message: ; 信息: ; Category: System.Web.Http.Controllers 类别:System.Web.Http.Controllers

  • In production environment, not successful (in short form): 在生产环境中,没有成功 (简短形式):

Message: http://myserver/api/order/12 ; 消息: http://myserver/api/order/12 ; Category: System.Web.Http.Request 类别:System.Web.Http.Request

Operator: DefaultHttpControllerSelector; 运算符:DefaultHttpControllerSelector; Operation: SelectController; 操作:SelectController; Message: Route="controller:order,id:12"; 消息:Route =“controller:order,id:12”; Category: System.Web.Http.Controllers 类别: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; 运算符:DefaultContentNegotiator; Operation: Negotiate; 操作:谈判; Message: Type = "HttpError" ... more 消息:Type =“HttpError”... 更多

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. 感谢Kiran Challa的评论和来自此答案的源代码,我能够发现生产服务器上缺少一个程序集(SQL Server Reporting Services的ReportViewer 11 assembly )。

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. 虽然这个程序ApiController没有ApiController ,但它似乎导致找不到程序ApiController控制器 - 在这种情况下是我的Web项目的程序集 - 引用了缺少的程序集。

Apparently this behaviour is related to this piece of code from the Web API's DefaultHttpControllerTypeResolver source: 显然,这种行为与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)));
    }
}

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. 我不知道是否必须采用这种方式,我对代码中的注释并不十分确信,但是这个问题catch ... continue阻止对可能存在的问题保持沉默,这花费了我很多时间和挫折感找到它。 I even knew that the ReportViewer wasn't installed yet. 我甚至知道还没有安装ReportViewer 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! 我试图安装它和依赖程序集,但它被服务器上的另一个正在运行的进程阻止,所以我决定推迟安装,直到我可以联系管理员并首先关注MVC和WebAPI测试 - 大错! 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. 没有Kiran的调试代码片段,我从来没有想过ReportViewer.dll的存在可能与控制器类型解析有关。

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. 在我看来,对于像我这样对Web API内部工作没有更深入了解的普通开发人员来说,还有改进的空间。

After installing the missing ReportViewer.dll the problem disappeared. 安装丢失的ReportViewer.dll ,问题就消失了。

Here are questions about the same symptom which might have the same reason: 以下是有关同一症状的问题, 可能有相同的原因:

Edit 编辑

I have issued a request for improvement on CodePlex: 我已经发出了对CodePlex的改进请求:

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

Edit 2 (Aug 11 '13) 编辑2(2013年8月11日)

The issue has been fixed for WebAPI v5.0 RC. WebAPI v5.0 RC已修复此问题。 See the link above to the workitem and its comments section for details. 有关详细信息,请参阅上面的工作项链接及其注释部分。

Great resources in this answer, however, I was getting a 404 for what turned out to be a pretty silly reason: 然而,在这个答案中有很好的资源,我得到了404,结果是一个非常愚蠢的原因:

  1. I created a WiX installer for my API project 我为我的API项目创建了一个WiX安装程序
  2. Installed it on a test VM (virtual machine) 将其安装在测试VM(虚拟机)上
  3. Requested for the a URI that the API should serve 请求API应该提供的URI
  4. BANG! 砰! 404 :( 404 :(

It turned out that I had missed packaging and deploying the Global.asax to the root of the virtual directory in my deployment. 事实证明,我错过了打包并将Global.asax部署到部署中虚拟目录的根目录。 Adding this here for the benefit of goofies like myself :) 在这里添加这个为了像我这样的傻瓜的好处:)

I had the same issue in a remote server, but when I execute on a localhost works fine. 我在远程服务器上遇到了同样的问题,但是当我在localhost上执行时工作正常。

My solution was: 我的解决方案是:

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

I hope, that this works for you. 我希望,这对你有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM