【问题标题】:All requests to ASP.NET Web API return 404 error对 ASP.NET Web API 的所有请求都返回 404 错误
【发布时间】:2013-05-24 15:51:22
【问题描述】:

我有一个包含 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 Route Debugger 添加到应用程序中。如果我使用像http://myserver/api/order/12 这样的有效路线,我会得到以下结果:

对我来说,这意味着找到了正确的路由模板Api/{Controller}/{Id},并将其正确解析为控制器OrderId=12。控制器(源自 ApiController)存在于所有 MVC 控制器所在的 Web 程序集中。

但是,我不知道状态 000 可能意味着什么以及为什么没有显示“路线选择”部分(即使程序集不包含单个 ApiController,通常也会出现这种情况,请参阅上面链接页面上的屏幕截图)。不知何故,似乎没有找到ApiController,甚至没有搜索到,或者搜索静默失败。

IIS 日志文件没有显示任何有用的信息。更改各种应用程序池设置并为测试和真实应用程序使用相同的应用程序池并没有帮助。

我目前正在从应用程序中删除“功能”、配置设置、第三方程序集等,最终将其缩小到测试应用程序的小尺寸,并希望它在某个时候启动上班。

有人知道问题可能是什么吗?此外,非常欢迎任何可能找到原因的调试或日志记录想法。

编辑

感谢 Darrel Miller 在下方 cmets 中的提示,我已集成 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;操作:协商;信息: 类型 = "HttpError" ... 更多

【问题讨论】:

  • @Liel:只有默认路由Api/{controller}/{id}id 设置为默认RouteParameter.Optional。如前所述,它适用于开发环境。不注册Web API路由还能用吗?
  • 我注意到 Product Environment 有 HttpError 类型的 Neogiate 操作。当您提出请求时,您看到了什么错误?您可以尝试将config.IncludeErrorDetailPolicy 设置为Always 并查看它的含义吗?此外,如果您的生产环境中不存在所有必需的程序集,我怀疑在解析程序集时可能会出现问题。要看看是不是这样,你可以做我在这篇文章中提到的一些事情:stackoverflow.com/questions/16673851/…
  • @KiranChalla:非常感谢您!!!这是一个缺少的程序集(请参阅下面的答案)。您能否发表您对大会决议的评论并链接到您的帖子作为答案?我会接受的。顺便说一句:您认为 Web API 源代码中的“我们故意忽略所有异常......”部分是否有改进 :)
  • 很高兴有帮助!!...是的,我也认为应该进一步改善体验,因为许多用户似乎都遇到了这个问题...您可以在这里提出问题吗? :aspnetwebstack.codeplex.com/workitem/list/basic

标签: asp.net .net asp.net-mvc asp.net-mvc-4 asp.net-web-api


【解决方案1】:

感谢Kiran Challa's 的注释和来自this answer 的源代码,我能够确定生产服务器上缺少一个程序集(SQL Server Reporting Services 的ReportViewer 11 assembly)。

虽然ApiController 不在此程序集中,但似乎导致程序集中的控制器(在本例中为我的 Web 项目的程序集)未找到引用缺少的程序集。

显然这种行为与Web API's 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 的调试代码 sn-p,我永远不会想到 ReportViewer.dll 的存在可能与控制器类型解析有关。

在我看来,对于像我这样对 Web API 的内部工作没有更深入了解的普通开发人员来说,还有改进的余地。

安装缺少的ReportViewer.dll后问题就消失了。

以下是关于相同症状的问题,可能有相同的原因:

编辑

我已发出对 CodePlex 的改进请求:

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

编辑 2(2013 年 8 月 11 日)

该问题已针对 WebAPI v5.0 RC 进行了修复。有关详细信息,请参阅上面指向工作项及其 cmets 部分的链接。

【讨论】:

  • 你在哪里找到这个大会?我只看到网络表单的东西。
  • @RaySülzer:它是 my 项目的一部分。如果你不使用 SSRS,你的项目中不会有这个程序集。
【解决方案2】:

这个答案中有很多资源,但是,我得到了 404,结果证明这是一个非常愚蠢的原因:

  1. 我为我的 API 项目创建了一个 WiX 安装程序
  2. 将其安装在测试 VM(虚拟机)上
  3. 请求 API 应提供的 URI
  4. 砰! 404:(

事实证明,我错过了将 Global.asax 打包和部署到我的部署中虚拟目录的根目录。在这里添加这个是为了像我这样的傻瓜:)

【讨论】:

  • 最后一句话对我来说是一个线索,我在发布时通过检查“Pre-compile before....”使其工作,它就像我的本地服务器一样工作。
  • 我觉得自己像个白痴!谢谢你的最后一段 - 我完全忘记了 global.asax 文件!!!
【解决方案3】:

我在远程服务器上遇到了同样的问题,但是当我在本地主机上执行时工作正常。

我的解决方案是:

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

我希望这对你有用。

【讨论】:

    猜你喜欢
    • 2013-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多