1
Vote

HttpMessageInvoker object disposed exception

description

Hello,

I am hosting a Web API REST service using Owin and a typical startup class, for example:
        public void Configuration(IAppBuilder builder)
        {
            System.Diagnostics.Debug.WriteLine("Startup - Configuring the HttpServer.");
            var server = new HttpServer();
            WebApiConfig.Register(server);
            builder.UseWebApi(server);
            builder.UseStageMarker(PipelineStage.Authenticate);
        }
This all works well, however I have noticed that every now and then on the very 1st request to the service I see the following error:
<html>
    <head>
        <title>Cannot access a disposed object.<br>Object name: 'System.Net.Http.HttpMessageInvoker'.</title>
        <meta name="viewport" content="width=device-width" />
        <style>
         body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} 
         p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
         b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
         H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
         H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
         pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt}
         .marker {font-weight: bold; color: black;text-decoration: none;}
         .version {color: gray;}
         .error {margin-bottom: 10px;}
         .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
         @media screen and (max-width: 639px) {
          pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; }
         }
         @media screen and (max-width: 479px) {
          pre { width: 280px; }
         }
        </style>
    </head>

    <body bgcolor="white">

            <span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>

            <h2> <i>Cannot access a disposed object.<br>Object name: 'System.Net.Http.HttpMessageInvoker'.</i> </h2></span>

            <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

            <b> Description: </b>An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

            <br><br>

            <b> Exception Details: </b>System.ObjectDisposedException: Cannot access a disposed object.<br>Object name: 'System.Net.Http.HttpMessageInvoker'.<br><br>

            <b>Source Error:</b> <br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code>

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.</code>

                  </td>
               </tr>
            </table>

            <br>

            <b>Stack Trace:</b> <br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code><pre>

[ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Http.HttpMessageInvoker'.]
   System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) +426915
   System.Web.Http.Owin.<InvokeCore>d__0.MoveNext() +1561
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +32
   Microsoft.Owin.Host.SystemWeb.Infrastructure.ErrorState.Rethrow() +62
   Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar) +185
   Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) +55
   System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +434
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288
</pre></code>

                  </td>
               </tr>
            </table>

            <br>

            <hr width=100% size=1 color=silver>

            <b>Version Information:</b> Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.34009

            </font>

    </body>
</html>

[ObjectDisposedException]: Cannot access a disposed object.
Object name: 'System.Net.Http.HttpMessageInvoker'.
   at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Web.Http.Owin.HttpMessageHandlerAdapter.<InvokeCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Owin.Host.SystemWeb.Infrastructure.ErrorState.Rethrow()
   at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar)
   at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar)
   at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
I added some basic debug logging statements to the application and saw that on the first request my logging statement "Startup - Configuring the HttpServer" is output as expected, and I see the error I mentioned. Then on the second request I make I see the logging statement again and the request succeeds without error.

This leads me to believe that for some reason the Owin runtime components are being disposed during the first request and need to be re-created during the second request. I have only produced this with the Azure emulator so far with the following steps, and it is not re-producible every time.
  1. Ensure debugger is stopped.
  2. Ensure both compute and storage emulators are stopped.
  3. Clean and rebuild my solution.
  4. Start debugging which also deploys to emulator.
  5. Send first request, observe owin runtime created and exception -> doesn't happen every time, maybe 1 times out of 20.
  6. Send second request and observer owin runtime created and no exception.

comments

yishaigalatzer wrote Aug 13, 2014 at 9:52 PM

@Kiran can you please investigate and work with Chris Ross/Prabu as necessary

kichalla wrote Sep 17, 2014 at 8:51 PM

@thebothead:
Thanks for reporting the issue.
I see that you are trying to use Web API OWIN adapter(System.Web.Http.Owin.dll) in IIS. This is not a supported scenario. The "System.Web.Http.Owin.dll" is meant to be used when self-hosting.

Can you please elaborate as to what is the scenario that you are trying here?

yishaigalatzer wrote Oct 3, 2014 at 7:20 PM

We haven't heard anything back for over a month and a half now.

Closing, but feel free to re-activate if you can add more input about the scenario you are trying to address.

yishaigalatzer wrote Oct 3, 2014 at 7:20 PM

** Closed by yishaigalatzer 10/03/2014 12:20PM

thebothead wrote Oct 23, 2014 at 7:54 PM

Hello,

Thanks for you reply. We are hosting an ASP.NET Web API w/ OData in Azure (IIS). We are not self-hosting the web application. We are using the Owin startup class to initialize the web application as shown above.

The OWIN packages we have installed are:
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.0" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.0-rc2" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.0-rc2" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />

We have not installed the self-hosting OWIN package (i.e. Microsoft.AspNet.WebApi.OwinSelfHost). I assume that would be the package to use if we were self-hosting the web application in a console application or something of that nature.

Can you please advise on what you think the issue is here in terms of the OWIN packages we are using within IIS?

kichalla wrote Oct 24, 2014 at 12:35 AM

If you are NOT self-hosting, do not use Microsoft.AspNet.WebApi.Owin package with IIS...this package is only supposed to be used with self hosting..

thebothead wrote Oct 24, 2014 at 12:51 PM

OK, thanks. What is the appropriate OWIN package to use for Web API when hosting with IIS?

thebothead wrote Oct 24, 2014 at 12:56 PM

The MSFT example for OWIN and IIS use exactly that package though...

https://code.msdn.microsoft.com/The-web-application-with-e57d6345

kichalla wrote Oct 24, 2014 at 5:38 PM

@thebothead:
  1. The sample you provided is not from us. External users can also upload them to the site.
  2. At the minimum you need the following packages to be installed:
    a. Microsoft.AspNet.WebApi (this is a 'meta' package which should bring in web api packages like ".WebHost", ".Core", ".Client" etc.).
    b. Microsoft.AspNet.SignalR.SystemWeb (this should bring in SignalR related dependencies)

thebothead wrote Oct 24, 2014 at 6:40 PM

@kichalla:
Thanks for clarifying that. I am trying to understand what the correct way to use OWIN with Web API hosted in IIS is. I have only been told so far that what I am doing is incorrect, but I have not been able to understand what the correct way to use OWIN with Web API hosted in IIS is.

Is what I am trying to do feasible, and if so can you please instruct on what the correct way to integrate OWIN with Web API is when hosting in IIS?

Thanks.

kichalla wrote Oct 24, 2014 at 11:09 PM

@thebothead:
I have now created an IIS hosted Web API + Owin-based SignalR sample and shared it below:

http://1drv.ms/1sZBdu1

if you take a look at this sample's packages.config, you should see that i do not have any reference to 'Microsoft.AspNet.WebApi.Owin' package:
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="AngularJS.Core" version="1.3.0" targetFramework="net451" />
  <package id="bootstrap" version="3.2.0" targetFramework="net451" />
  <package id="jQuery" version="1.9.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.SignalR.Core" version="2.1.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.SignalR.JS" version="2.1.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.SignalR.SystemWeb" version="2.1.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebApi" version="5.1.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.1.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.1.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.1.2" targetFramework="net451" />
  <package id="Microsoft.Owin" version="2.0.1" targetFramework="net451" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="2.0.1" targetFramework="net451" />
  <package id="Microsoft.Owin.Security" version="2.0.1" targetFramework="net451" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net451" />
  <package id="Owin" version="1.0" targetFramework="net451" />
</packages>

thebothead wrote Oct 27, 2014 at 12:33 PM

Thanks, so in the example I mentioned where the following is performed:
        public void Configuration(IAppBuilder appBuilder) 
        { 
            appBuilder.MapSignalR(); 
 
            var httpConfiguration = new HttpConfiguration(); 
             
            httpConfiguration.Formatters.Clear(); 
            httpConfiguration.Formatters.Add(new JsonMediaTypeFormatter()); 
             
            httpConfiguration.Formatters.JsonFormatter.SerializerSettings =  
                new JsonSerializerSettings 
            { 
                ContractResolver = new CamelCasePropertyNamesContractResolver() 
            }; 
 
            httpConfiguration.Routes.MapHttpRoute( 
                name: "DefaultApi", 
                routeTemplate: "api/{controller}/{id}", 
                defaults: new { id = RouteParameter.Optional }); 
 
            appBuilder.UseWebApi(httpConfiguration); 
        } 
This is NOT the recommended approach with hosting in IIS, and should only be done with self-hosting. In your example you hook up to the following even when using OWIN:
        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);
        }
So appBuilder.UseWebApi(httpConfiguration); is just a bootstrap for self-hosting scenarios?

Thanks again.

kichalla wrote Oct 27, 2014 at 2:34 PM

Yes...right...UseWebApi extension should be used only with self-hosting scenarios...since we are all on the same page, I am closing this issue as by-design...please let us know if you have any more questions...

Thanks,
Kiran

kichalla wrote Oct 27, 2014 at 2:34 PM

** Closed by kichalla 10/27/2014 7:34AM

thebothead wrote Oct 28, 2014 at 3:44 PM

Hi Kiran,

Sorry to, as they say, beat a dead horse on this issue... But I also found the following example on the aspnet.codeplex.com website by your team here with the following description:

Katana Samples
Web API | Source Code
This sample shows how to host OWIN in IIS and add Web API to the OWIN pipeline.

This sample performs the following:
        // Invoked once at startup to configure your application.
        public void Configuration(IAppBuilder builder)
        {
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute("Default", "{controller}/{customerID}", new { controller = "Customer", customerID = RouteParameter.Optional });

            config.Formatters.XmlFormatter.UseXmlSerializer = true;
            config.Formatters.Remove(config.Formatters.JsonFormatter);
            // config.Formatters.JsonFormatter.UseDataContractJsonSerializer = true;

            builder.UseWebApi(config);
        }
and uses the packages:
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.0" targetFramework="net45" />
  <package id="Microsoft.Owin" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="3.0.0" targetFramework="net45" />
So... with all this, is the example provided here by your team also incorrect?

Thanks.

kichalla wrote Oct 29, 2014 at 3:28 PM

@thebothead:
Thanks for finding this out!...right, this sample shouldn't have been using Microsoft.AspNet.WebApi.Owin in IIS as it was never intended to be used in that host...we will investigate the issue further to see why this exception happens...but meanwhile you could follow the approach mentioned in the sample that I provided earlier...

Thanks,
Kiran

thebothead wrote Oct 29, 2014 at 6:02 PM

OK great, thanks!!

darielmarlow wrote Mar 3 at 11:59 PM

Sorry to rehash this yet again. We were seeing some strange things happening and followed the advice in this discussion: http://katanaproject.codeplex.com/discussions/540202

It says the following:
The request flow looks like this:
IIS->SystemWeb->OWIN->SystemWeb->WebApi

The problem is that SystemWeb doesn't reliably fire the events we need when components that run after us send the headers.

For WebApi you can work around this by switching from Microsoft.AspNet.WebApi.WebHost to Microsoft.AspNet.WebApi.Owin. Then you move your WebApi config into the Startup class like this:
https://aspnet.codeplex.com/SourceControl/latest#Samples/Katana/WebApi/Startup.cs

This makes your request flow look like this:
IIS->SystemWeb->OWIN->WebApi

Which keeps SystemWeb from getting in the way.
Will you clarify the correct way. It seems we're trading one set of issues for another.

Thanks!