Wednesday, March 30, 2016

OWIN on IIS7

I have a long journey behind me with trying to deploy my ASP.NET application using OWIN on IIS7. But finally, I was successful.

Most articles mention:
  • Ensure that Microsoft.Owin.Host.SystemWeb.dll is in the bin folder of the web application
  • Run app pool in V4.0 integrated mode
  • Add runAllManagedModulesForAllRequests to your Web.config:
    <system.webServer>
      <modules runAllManagedModulesForAllRequests="true" />       
    </system.webServer>
Unfortunately, this was not enough for me. The final hint I found in the Katana Wiki. I had to add
app.UseStageMarker(PipelineStage.MapHandler);
to the end of my Startup.Configuration() method. Really important is “the end”.

Some details, you can find in OWIN Middleware in the IIS integrated pipeline. The article describes how the pipelines in OWIN and ASP.NET relate. Very helpful for me was the tracing of the current pipeline stage.

My code was something like
public void Configuration(IAppBuilder app)
{
  app.UseStaticFiles();
  app.MapSignalR();
  app.UseWebApi();
}
With the tracing, I saw the following the following stages on IIS7:
  • UseStaticFiles: AuthorizeRequest
  • MapSignalR: AuthorizeRequest
  • UseWebApi: missing
On IIS8.5, the behavior was slightly different:
  • UseStaticFiles: AuthorizeRequest
  • MapSignalR: AuthorizeRequest
  • UseWebApi: PreExecuteRequestHandler
On IIS8.5, everything was working, but on IIS7, WebApi couldn’t work, since it was not reached in the pipeline.

My first suspicion was, that MapSignalR did prevent the further processing. But this was completely wrong. Due to MapSignalR at least everything before (including SignalR) worked, since MapSignalR is setting the stage marker PostAuthorize.

Unfortunately everything later than MapHandler is not executed on IIS7. Therefore I had to add the appropriate call at the end of my method:
public void Configuration(IAppBuilder app)
{
  app.UseStaticFiles();
  app.MapSignalR();
  app.UseWebApi();
  app.UseStageMarker(PipelineStage.MapHandler);
}
Now everything is working latest in stage MapRequestHandler, in my case:
  • UseStaticFiles: AuthorizeRequest
  • MapSignalR: AuthorizeRequest
  • UseWebApi: MapRequestHandler
Unfortunately, I still do not know, why this is necessary. But at least I have a working solution now.

2 comments:

  1. what does app.UseStageMarker(PipelineStage.MapHandler); really do? I found that if I have it in there, I get an error in my .asmx Web Service.

    ReplyDelete
    Replies
    1. It is just a marker to tell the runtime, where in the IIS pipeline the OWIN middleware should be executed. As you can see in https://msdn.microsoft.com/en-us/library/system.web.httpapplication(v=vs.110).aspx, IIS knows in total 19 different stages.

      If you have app.UseStageMarker(PipelineStage.MapHandler) in your startup code, it means that every OWIN middleware configured before runs latest in the MapRequestHandler event.

      Beside this: asmx is a very old technology, OWIN is quite new. So maybe they are simply not compatible?

      Delete