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.

Tuesday, March 29, 2016

Do not use Microsoft.AspNet.SignalR.Owin any longer

Today I had some strange warnings in one of my web projects using SignalR and Owin. After longer probing and testing, also asking at Stack Overflow, I finally found the reason.

I used the following NuGet packages (beside others):

Both components contain some classes in the same namespace (e.g. Microsoft.AspNet.SignalR.WebSockets.DefaultWebSocketHandler). Unfortunately, not all implementations (worse: not all signatures) are identical. This caused my problems.

The solution is simple: just do not use the NuGet package Microsoft.AspNet.SignalR.Owin any longer! Microsoft.AspNet.SignalR.Core is enough.

Owin Default Files

I just came around the problem that I wanted to serve static files via Owin. Therefore I added the NuGet package Microsoft.Owin.StaticFiles, and added the following to my Startup class:

app.UseStaticFiles();
app.UseDefaultFiles(new DefaultFilesOptions 
  { 
    DefaultFileNames = new[] { "index.html" } 
  });

With this, I was able to serve static files, but the default document didn’t work. I always got a HTTP 404 response. Even though I saw the access to the file in the Process Monitor. Finally, I found the solution in one of the answers to a question of Stack Overflow. I had to call UseDefaultFiles first! Before UseStaticFiles:

app.UseDefaultFiles(new DefaultFilesOptions 
  { 
    DefaultFileNames = new[] { "index.html" } 
  });
app.UseStaticFiles();

Sunday, March 20, 2016

CodeAnalysis broken on TFS build

Today I created a new build on TFS. The compile step was successful, but not the code analysis. It failed with

(RunCodeAnalysis target) ->
  MSBUILD : error : CA0001 : The following error was encountered while reading module '...': Could not resolve member reference: [System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]System.Net.Http.Formatting.BaseJsonMediaTypeFormatter::get_SerializerSettings.

This was quite confusing, since I had referenced the correct version. Since I had the same problem already 4 weeks ago, but couldn’t remember it today, I decided to write this post.

In the detailed build output I found also

Unified primary reference "Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed".
Using this version instead of original version "6.0.0.0" in "...\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll" because AutoUnify is 'true'.

System.Net.Http.Formatting is referencing Newtonsoft.Json in version 6.0.0.0, but I referenced it in version 8.0.0.0. This doesn’t make problems with the build, and also at runtime, there are no problems (due to the assemblyBinding). But code analysis cannot handle it out of the box.

The solution is to enhance the FxCop command with /assemblyCompareMode:StrongNameIgnoringVersion. I did this by adding a property to my .csproj file:

<propertygroup>
  <codeanalysisadditionaloptions>/assemblyCompareMode:StrongNameIgnoringVersion</codeanalysisadditionaloptions>
</propertygroup>

That’s it!