The OWIN specification defines a delegate called appFunc that allows any OWIN compatible host to work with any OWIN compatible application. This post shows you how to turn an ASP.NET Web API into an AppFunc.
AppFunc is defined as ,
using AppFunc = Func<IDictionary<string, object>,Task>;
In other words, a function that accepts an object that implements IDictionary<string,object> and returns a Task. The dictionary contains all the OWIN environment values and the Task is used to signal when the HTTP application has finished processing the request.
Microsoft have built OWIN infrastructure code, aka Katana, to support OWIN applications and host. Unfortunately when creating the glue code that allows Web API to run on OWIN hosts, they hid the appFunc behind "helper" code. Using Katana does add a whole lot of value, but I feel that being required to use a Katana-enabled host to host a Katana-enabled application kind of defeats the point of OWIN, even though OWIN is being used under the covers.
Fortunately, it is not a big task to use the Katana Web API infrastructure and expose it as a real OWIN appFunc. I do use the Katana Web API adapter code to avoid having to re-write the code that maps the Owin environment into HttpRequestMessage and HttpResponseMessage. You can install this by using the Microsoft.AspNet.WebApi.Owin nuget package.
public static class WebApiAdapter { public static Func<IDictionary<string, object>, Task>
CreateWebApiAppFunc(
HttpConfiguration config,
HttpMessageHandlerOptions options = null) { var app = new HttpServer(config); if (options == null) { options = new HttpMessageHandlerOptions() { MessageHandler = app, BufferPolicySelector = new OwinBufferPolicySelector(), ExceptionLogger = new WebApiExceptionLogger(), ExceptionHandler = new WebApiExceptionHandler() }; } var handler = new HttpMessageHandlerAdapter(null, options); return (env) => handler.Invoke(new OwinContext(env)); } }<span class="kwrd">public</span> <span class="kwrd">class</span> WebApiExceptionLogger : IExceptionLogger { <span class="kwrd">public</span> Task LogAsync(ExceptionLoggerContext context, <br> CancellationToken cancellationToken) { <span class="kwrd">return</span> Task.FromResult<<span class="kwrd">object</span>>(<span class="kwrd">null</span>); } } <span class="kwrd">public</span> <span class="kwrd">class</span> WebApiExceptionHandler : IExceptionHandler { <span class="kwrd">public</span> Task HandleAsync(ExceptionHandlerContext context, <br> CancellationToken cancellationToken) { <span class="kwrd">return</span> Task.FromResult<<span class="kwrd">object</span>>(<span class="kwrd">null</span>); } }</pre>The current the ExceptionLogger and ExceptionHandler are "do nothing" implementations, but these can be replaced with application specific code. Passing an HttpConfiguration instance to the CreateWebApiAppFunc method will return an OWIN appFunc that should work with any OWIN host.
There is an example of how you can host an AppFunc in my earlier blog post.