Web API 2 批量请求路由正确但无数据或500错误

Web API 2 Batch Request Routes Correctly But No Data or 500 Error

我最近创建了一个新的 Web API 2 项目,并且正在为我的 RESTful API 使用大部分默认脚手架。我正在尝试添加批处理支持并一直使用这两个资源作为指南:

http://blogs.msdn.com/b/webdev/archive/2013/11/01/introducing-batch-support-in-web-api-and-web-api-odata.aspx

https://aspnetwebstack.codeplex.com/wikipage?title=Web+API+Request+Batching

我添加了路由,并使用了框架提供的 DefaultHttpBatchHandler 所以我的 WebApiConfig.cs 看起来像这样:

using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
using System.Web.Http.Batch;

namespace WebAPI_Test
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
        // Web API configuration and services
        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpBatchRoute(
            routeName: "batch",
            routeTemplate: "api/$batch",
            batchHandler: new DefaultHttpBatchHandler(GlobalConfiguration.DefaultServer)
        );

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        }
    }
}

我还有以下控制器:

using System;
using System.Web.Http;

namespace WebAPI_Test.Controllers
{
    public class CustomersController : ApiController
    {
        public string Get(string id)
        {
        string val = String.Format("Customer: {0}", id);

        return val;
        }

    }
}

我可以通过 Fiddler4 发出以下 HTTP 请求并获得成功响应:

GET http://example.com:8010/WebAPI_Test/api/customers/abs HTTP/1.1
User-Agent: Fiddler
Host: example.com:8010

我也可以成功命中批处理终点并获得 200 响应,但是,当我这样做时,我没有获得任何数据,而且我的控制器上的断点从未命中。使用以下请求:

POST http://example.com:8010/WebAPI_Test/api/$batch HTTP/1.1
User-Agent: Fiddler
Content-Type: multipart/mixed; boundary=abc101
Host: example.com:8010
Accept: multipart/mixed
Accept-Charset: UTF-8
Content-Length: 179


--abc101
Content-Type: application/http; msgtype=request
GET http://example.com:8010/WebAPI_Test/api/Customers/abc HTTP/1.1
Host: example.com:8010
--abc101--

我得到:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 84
Content-Type: multipart/mixed; boundary="1c950245-84e8-4c1b-8545-58e93cdd7b25"
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 18 Feb 2016 00:09:54 GMT

--1c950245-84e8-4c1b-8545-58e93cdd7b25

--1c950245-84e8-4c1b-8545-58e93cdd7b25--

我注意到在上面提到的两个 link 中,后续请求都使用相对路径。所以我将我的请求正文修改为:

--abc101
Content-Type: application/http; msgtype=request
GET /WebAPI_Test/api/Customers/abc HTTP/1.1
Host: example.com:8010
--abc101--

但是,现在我只收到一个通用的 500: Internal Server Error 响应,我的 none 断点被命中。我想错误是从 .NET 库之一抛出的,但我没有得到堆栈跟踪。

在上面的第一个 link 中,作者使用的是 Owin 和自托管。我注意到他在他的 app 对象上调用了 UseWebApi 方法。虽然我是通过 IIS 托管的,但我还是决定试一试(诚然,运行 这里没有想法)。在我的 StartUp.cs 文件中,我有以下内容:

using Microsoft.Owin;
using Owin;
using System.Web.Http;

[assembly: OwinStartup(typeof(WebAPI_Test.Startup))]

namespace WebAPI_Test
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
        ConfigureAuth(app);
        app.UseWebApi(GlobalConfiguration.DefaultServer);
        }
    }
}

使用我上面提到的第一批 HTTP 请求(在请求正文中有完整路径)我得到了相同的结果:200 但没有数据并且永远不会命中控制器方法。

当我只尝试使用请求正文中的相对路径时,我仍然收到 500 错误,但我得到的不是通用 "An error as occurred" 消息,而是以下消息:

{
  "Message": "An error has occurred.",
  "ExceptionMessage":"Error parsing HTTP message header byte 5 of message System.Byte[].",
  "ExceptionType":"System.InvalidOperationException","StackTrace":"   at System.Net.Http.HttpContentMessageExtensions.<ReadAsHttpRequestMessageAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Batch.DefaultHttpBatchHandler.<ParseBatchRequestsAsync>d__13.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Batch.DefaultHttpBatchHandler.<ProcessBatchAsync>d__1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Batch.HttpBatchHandler.<SendAsync>d__0.MoveNext()"
}

我试图将我的 Customers 控制器 get 方法修改为 运行 异步(即 return 一个 Task<IHttpActionResult> 尽管因为我所做的只是 returning 一个字符串我知道那是多么毫无意义)但我仍然收到相同的错误消息。

我希望我遗漏了一些非常明显的东西。我没能找到任何解决此问题的 forums/questions/resources。如果有人有任何见解或帮助,将不胜感激。如果需要,我可以 post 更多我的配置代码(尽管它是非常标准的脚手架)。提前致谢!

这已通过更新 IIS 得到修复。

我应该早点更新这个,以防其他人看到它;如果还有其他人使用 Windows Server 2008/Windows 2007,这最终通过 IIS 更新得到解决。我希望我可以报告问题最初是什么,但是一旦它起作用,就不需要进一步调查(至少从我当时的雇主的角度来看不需要)。