-
Notifications
You must be signed in to change notification settings - Fork 66
Owin & Katana
In the 0.9 release of Simple.Web we announced improved support for running Simple.Web with an OWIN-compatible web-server, particular focus on compatibility with the upcoming release of Katana v2. We also introduced a new self-hosting package aimed at reducing boiler-plate code associated with bootstrapping.
** ON A SIDE NOTE **
OWIN is a standard interface specification born into the community by Benjamin van der Veen ~2010 to provide a common "glue" between server, and framework or module. Katana is Microsoft's own implementation of an OWIN-compatible web server with accompanying set of modules.
Simple.Web was built around OWIN and it's delegate method signature, but it relied on it's sister projects Fix and Flux for assurance. With the emergence of viable server alternatives (such as Katana) we found areas for improvement, mainly where interpretation of the specification could result in an incompatibility.
Not strictly part of the specification the community has grown towards a set of common conventions:
It's common for extension methods to be provided to reduce boilerplate code and complexity. In the case of Simple.Web we have introduced UseSimpleWeb()
.
Previously
using AppFunc = System.Func<System.Collections.Generic.IDictionary<string, object>, System.Threading.Tasks.Task>;
app.Use(new Func<AppFunc, AppFunc>(ignoreNextApp => (AppFunc)Simple.Web.Application.Run);
Now
app.UseSimpleWeb();
OWIN-compatible servers often scan for a Startup
class with a Configuration
method as an application entry point. To reduce boilerplate code we have introduced Simple.Web.OwinSupport.OwinStartupBase
.
Minimal
public class Startup : OwinStartupBase { }
AppBuilder
public class Startup : OwinStartupBase
{
public Startup() : base(builder => {
builder.UseErrorPage();
builder.UseWelcomePage("/owin");
builder.UseSimpleWeb();
});
}
Katana supports different approaches for hosting your application. We have built a set of sample projects to illustrate SimpleWeb's compatibility. Find below some example code snippets.
To reduce boiler-plate code when bootstraping your server from a console project we have introduced a new self-hosting package that uses Katana v2.
Minimal
namespace OwinConsoleHost
{
using System;
using Simple.Web.Hosting.Self;
internal class Program
{
private static void Main(string[] args)
{
new OwinSelfHost().Run();
}
}
}
Options
namespace OwinConsoleHost
{
using System;
using Simple.Web.Hosting.Self;
internal class Program
{
private static void Main(string[] args)
{
new OwinSelfHost().Run("localhost", port: 3333, ssl: false);
}
}
}
AppBuilder
namespace OwinConsoleHost
{
using System;
using Simple.Web.Hosting.Self;
internal class Program
{
private static void Main(string[] args)
{
new OwinSelfHost(
builder =>
{
builder.UseErrorPage();
builder.UseSimpleWeb();
})
.Run();
}
}
}
Custom
namespace OwinConsoleHost
{
using System;
using Simple.Web.Hosting.Self;
internal class Program
{
private static void Main(string[] args)
{
var host = new OwinSelfHost();
using (host.Start(hostname: "localhost", port: 3333, ssl: false))
{
Console.WriteLine("Listening at http://localhost:3333. Press CTRL-C to stop.");
Console.CancelKeyPress += (sender, eventArgs) => Console.WriteLine("Stopping.");
while (true)
{
}
}
}
}
}
You can contain your application within a library project (assembly) and use Katanas' OwinHost.exe to bootstrap it. The easiest way to do this is by adding NuGet package OwinHost-mono
to your solution.
Startup.cs
[assembly: Microsoft.Owin.OwinStartup(typeof(OwinWebHost.Startup))]
namespace OwinWebHost
{
using Simple.Web.OwinSupport;
public class Startup : OwinStartupBase
{
}
}
To enable F5 run from Visual Studio you will need to add a StartAction to the bottom of your csproj file:
.csproj
<PropertyGroup>
<StartAction>Program</StartAction>
<StartProgram>$(ProjectDir)../packages/OwinHost-mono.2.0.0-rtw-20815-004/tools/OwinHost.exe</StartProgram>
</PropertyGroup>
Note You need to make sure your output path does not contain the project configuration (e.g. "debug") as OwinHost.exe doesn't like it. I have raised this with the Katana team but without resolution.
Support for Web Application project types comes via web.config
and Microsoft.Owin.OwinStartup
assembly attribute. Your web application will run on top of SystemWeb, including interactive debugging.
Startup.cs
[assembly: Microsoft.Owin.OwinStartup(typeof(OwinWebHost.Startup))]
namespace OwinWebHost
{
using Simple.Web.OwinSupport;
public class Startup : OwinStartupBase
{
}
}
web.config
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<appSettings>
<add key="owin:Configuration" value="KatanaWebApplication2.Startup.Configuration, KatanaWebApplication2" />
<add key="owin:SetCurrentDirectory" value="true" />
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpHandlers>
<clear />
<add verb="*" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb" />
</httpHandlers>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<remove name="RewriteModule" />
<remove name="OutputCache" />
<remove name="Session" />
<remove name="WindowsAuthentication" />
<remove name="FormsAuthentication" />
<remove name="DefaultAuthentication" />
<remove name="RoleManager" />
<remove name="UrlAuthorization" />
<remove name="FileAuthorization" />
<remove name="AnonymousIdentification" />
<remove name="Profile" />
<remove name="UrlMappingsModule" />
<remove name="ServiceModel-4.0" />
<remove name="UrlRoutingModule-4.0" />
<remove name="ScriptModule-4.0" />
</modules>
<handlers>
<clear />
<add name="Owin" verb="*" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb" />
</handlers>
<security>
<requestFiltering allowDoubleEscaping="true" allowHighBitCharacters="true">
<fileExtensions allowUnlisted="true">
<clear />
</fileExtensions>
<hiddenSegments>
<clear />
</hiddenSegments>
<verbs allowUnlisted="true" />
</requestFiltering>
</security>
</system.webServer>
</configuration>