This ASP.NET Web API poster is awesome!

tl;dr - It is very easy to write self-hosting C#/F# ASP.NET MVC/Web API application, without using any Visual Studio non-sense (templates, plugins, etc.)

Reading An overview of Project Katana (A HIGHLY RECOMMENDED READ) helped a lot understanding the relationship between the Microsoft web stack. OWIN is the spec laying out how to build middleware and web app in a chainable fashion. This is very similar to the apps concept in Express.js. Everything as small as authentication to as large as a web framework can be defined as a middleware.

Katana is an implementation of OWIN and related tools.

On top of this, you can then write ASP.NET MVC/Web API and host them as OWIN apps.

To self host a Web API app, there're two options,

  1. use OWIN selfhost (Microsoft.Owin.SelfHost)
  2. use Web API home brew selfhoting (System.Web.Http.SelfHost)

If #2 is chosen, then it's completely separated from the OWIN stack.

  • The core OWIN nuget package is OWIN
  • The core Katana nuget package is Microsoft.Owin
  • The OWIN self host package is Microsoft.Owin.SelfHost
  • The core ASP.NET Web API package is Microsoft.AspNet.WebApi.Core, but the assembly name is System.Web.Http (so f**king confusing)

Useful documents for developing Web API and self hosting:

Here's a vanilla Wep API application without any Visual Studio non-sense:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
namespace Foo
{
using System;
using System.Net;
using System.Threading;
using System.Linq;
using System.Collections.Generic;
using System.Text;

using Newtonsoft.Json;
using System.Web.Http;
using System.Web.Http.SelfHost;

/// <summary>
/// Main class
/// </summary>
public static class MainClass
{
static void Main(string[] args)
{
var addr = new Uri("http://localhost:8001");
using (var config = new HttpSelfHostConfiguration(addr))
{
config.Routes.MapHttpRoute("default", "api/{controller}");
using (var srv = new HttpSelfHostServer(config))
{
srv.OpenAsync().Wait();
Console.WriteLine("Server started");

Console.ReadLine();
Console.WriteLine("done");
}
}
}
}

public class ProductController : ApiController
{
public class Result
{
public int Code;
public object Metadata;
}

[HttpPost]
public Result Post([FromBody]int[] data)
{
return new Result
{
Code = 1,
Metadata = data,
};
}
}
}