Web API'在内存中'请求抛出异常

时间:2013-11-15 13:36:58

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

好的,我的情况要复杂得多,但有一种简单的方法可以重现。从一个全新的 ASP.NET MVC 4 Web应用程序项目开始,选择Web API作为模板,我只需在HomeController中添加第二个mvc操作,我需要在内部调用Web API。

 public async Task<string> TestAPI()
    {
        HttpServer server = new HttpServer(GlobalConfiguration.Configuration);
        using (HttpMessageInvoker messageInvoker = new HttpMessageInvoker(server, false))
        {
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:58233/api/values");
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var response = messageInvoker.SendAsync(request, new CancellationToken()).Result;
            return await response.Content.ReadAsStringAsync();
        }

        //server.Dispose(); - if I do that on the second request I get a "Cannot access a disposed object." exception
    }

那件事只适用于第一个请求。在随后的请求中,它会抛出

  

'DelegatingHandler'列表无效,因为该属性   'RequestMessageHandlerTracer'的'InnerHandler'不为空。参数   名称:处理程序

我真的需要在这里使用GlobalConfiguration.Configuration,因为我的系统是非常模块化/基于插件的,这使得在动作方法(或其他任何地方)内重建该配置非常困难。

2 个答案:

答案 0 :(得分:2)

我建议尝试在次要请求上重用HttpServer实例。在每个请求上创建和配置新服务器不是预期的用法,您可能会遇到一些边缘情况。设置DI机制并向控制器注入HttpServer的单例,或者尝试从某个静态属性访问它。

我也建议使用new HttpClient(httpServer)而不是HttpMessageInvoker。

答案 1 :(得分:0)

如果您有多个HttpServer使用相同的配置对象,并且配置包含非空的委派处理程序列表,则Web API中可能会出现同样的问题。

发生错误是因为MVC / Web API在第一次请求时构建了一个处理程序管道,其中包含所有委托处理程序(如果启用了请求跟踪,则为RequestMessageHandlerTracer)相互链接,后跟MVC服务器处理程序。

如果您有多个HttpServer使用相同的配置对象,并且配置对象包含委托处理程序,则第一个HttpServer将成功连接到管道中;但第二个不会,因为委托处理程序已经连接 - 相反它会在第一次请求/初始化时抛出此异常。

此处有关Web API案例的更多详细信息(概念上相同,但使用的是不同的类,并且修改稍有不同): webapi batching and delegating handlers

在我看来,MVC配置类应该是纯配置,不包含实际的委托处理程序。相反,配置类应该在初始化时创建新的委托处理程序。那么这个bug就不存在了。