我最近创建了一个新的Web API 2项目,并且正在使用我的RESTful API的大多数默认脚手架。我正在尝试添加批处理支持,并一直使用这两个资源作为指南:
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>
,虽然我正在做的是返回一个字符串,我看到它是多么无意义但是我仍然收到相同的错误消息。
我希望有一些令人痛苦的显而易见的事情。我无法找到任何解决此问题的论坛/问题/资源。如果有人有任何见解或帮助,我将不胜感激。如果需要,我可以发布更多我的配置代码(尽管它是非常标准的脚手架)。提前谢谢!
答案 0 :(得分:0)
此问题已通过IIS更新得到解决。
如果有人遇到它,我应该已经更新了一段时间;如果还有其他人使用Windows Server 2008 / Windows 2007,则可以通过更新IIS最终解决该问题。我希望我可以就问题最初的原因进行报告,但是一旦问题解决了,就不需要进一步调查了(至少从我当时的雇主的角度来看)。