Web API 2批处理请求路由正确但没有数据或500错误

时间:2016-01-10 22:58:21

标签: asp.net rest iis asp.net-web-api asp.net-web-api2

我最近创建了一个新的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--

我在上面引用的两个链接中都注意到后续请求使用了相对路径。所以我将我的请求主体修改为:

--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响应,并且没有任何断点被击中。我想这个错误是从一个.NET库中抛出的,但我没有得到堆栈跟踪。

在上面的第一个链接中,作者正在使用Owin和自托管。我注意到他在UseWebApi对象上调用了app方法。虽然我通过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错误,但是我没有得到以下通用的“发生错误”消息:

{
  "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方法以异步方式运行(即返回Task<IHttpActionResult>,虽然我正在做的是返回一个字符串,我看到它是多么无意义但是我仍然收到相同的错误消息。

我希望有一些令人痛苦的显而易见的事情。我无法找到任何解决此问题的论坛/问题/资源。如果有人有任何见解或帮助,我将不胜感激。如果需要,我可以发布更多我的配置代码(尽管它是非常标准的脚手架)。提前谢谢!

1 个答案:

答案 0 :(得分:0)

此问题已通过IIS更新得到解决。

如果有人遇到它,我应该已经更新了一段时间;如果还有其他人使用Windows Server 2008 / Windows 2007,则可以通过更新IIS最终解决该问题。我希望我可以就问题最初的原因进行报告,但是一旦问题解决了,就不需要进一步调查了(至少从我当时的雇主的角度来看)。