2

Ok, my situation is much more complicated but there is an easy way to reproduce. Starting with a fresh new ASP.NET MVC 4 Web Application project and selecting Web API as a template I just add a second mvc action to the HomeController where I need to call Web API internally.

 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
    }

that thing works only on the first request. On subsequent requests it throws with

The 'DelegatingHandler' list is invalid because the property 'InnerHandler' of 'RequestMessageHandlerTracer' is not null. Parameter name: handlers

I really need to use the GlobalConfiguration.Configuration here since my system is very modular/plugin based, which makes it really hard to reconstruct that configuration within the action method(or anywhere else).

2 Answers 2

2

I would suggest trying to re-use the HttpServer instance on secondary requests. Creating and configuring a new server on every request is not an expected usage and you are likely hitting some edge case. Either setup a DI mechanism and inject into your controller a singleton of the HttpServer, or try accessing it from some static property.

I also would suggest using new HttpClient(httpServer) instead of HttpMessageInvoker.

Sign up to request clarification or add additional context in comments.

Comments

0

The same issue can occur in Web API, if you have multiple HttpServers using the same configuration object, and the configuration contains a non-empty list of delegating handlers.

The error occurs because MVC/Web API builds a pipeline of handlers on first request, containing all the delegating handlers (eg RequestMessageHandlerTracer if request tracing is enabled) linked to each other, followed by the MVC server handler.

If you have multiple HttpServers using the same configuration object, and the config object contains delegating handlers, the first HttpServer will be successfully connected into a pipeline; but the second one won't, because the delegating handlers are already connected - instead it will throw this exception on first request/initialization.

More detail on the Web API case here (which is conceptually identical, but uses different classes and would have a slightly different fix): webapi batching and delegating handlers

In my opinion, the MVC configuration classes should be pure config, and not contain actual delegating handlers. Instead, the configuration classes should create new delegating handlers upon initialization. Then this bug wouldn't exist.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.