Setup Aspnet Web Api Owin Self Hosting - egnomerator/misc GitHub Wiki

Create an OWIN Self-Hosted Web API Application

Purpose

  1. Get started fairly quickly with a working self-hosted web API application with minimal extraneous files, references, and NuGet packages.
  2. Unlike most getting started tutorials involving OWIN self-hosting, this solution will work with .NET Framework 4.6.2 rather than .NET Core

Initial Application Creation

  1. Open Visual Studio
  2. Create an ASP.NET Web Application (.NET Framework)
  3. Choose the Empty Template, check the box for Web API, and click OK
  4. Set the Target Framework to .NET Framework 4.6.2

Nuget Packages

  1. Remove IIS-related nuget packages
    • Microsoft.AspNet.WebApi
    • Microsoft.AspNet.WebApi.WebHost
  2. Install OWIN Nuget Packages
    • Microsoft.Owin.Hosting (and dependencies)
    • Microsoft.Owin.Host.HttpListener
    • Microsoft.AspNet.WebApi.OwinSelfHost (and dependencies)

Implement Self-Hosting

  1. Add an application root-level public Program.cs class
  2. In the same file and namespace add a public Startup class
  3. Add the code
    // Add this method in the Program class
    static void Main()
    {
        const string baseAddress = "http://*:9000/";
    
        using (WebApp.Start<Startup>(baseAddress))
        {
            Console.WriteLine("Started!");
    
            Thread.Sleep(Timeout.Infinite);
    
            Console.WriteLine("Stopping");
        }
    }
    
    // Add these methods in the Startup class
    public void Configuration(IAppBuilder app)
    {
        var webApiConfig = ConfigureWebApi();
    
        app.UseWebApi(webApiConfig);
    }
    
    private HttpConfiguration ConfigureWebApi()
    {
        var config = new HttpConfiguration();
        config.Routes.MapHttpRoute(
            "DefaultApi",
            "api/{controller}/{id}",
            new { id = RouteParameter.Optional });
        return config;
    }

Why the Thread.Sleep(Timeout.Infinite); ?

  • This could just be a Console.ReadLine(), but this guide was originally documented with the intention of eventually running this application in a Docker container
  • Containers exit as soon as they have no tasks to complete, and this sleep line is used to prevent the container from closing so the server can continue to run, allowing the web API to be accessed

Convert to Console Application

In the web application properties

  1. Set the output type from class library to Console Application
  2. Set the Startup object to the Program class
  3. (optional) In the Web tab, select this option:

    Don't open a page. Wait for a request from an external application.

    • Selecting this option prevents a browser from automatically opening when starting to debug
    • Since this app does not contain a UI component - it's just a web service exposing an API - it might be unnecessary to open the browser along with a tool like Fiddler or Postman

Clean up

  1. Remove files Global.asax.cs and Global.asax
  2. Remove file WebApiConfig.cs and its containing App_Start folder

Implement API

  1. Add a ItemsController.cs class inheriting from ApiController in the Controllers folder
  2. Add a Item.cs class in the Models folder
  3. Add the code
    // Add these properties in the Item class
    public long Id { get; set; }
    public string Name { get; set; }
    
    // Add these methods in the controller
    // GET api/items
    [HttpGet]
    public IEnumerable<Item> Get()
    {
        return new List<Item>
        {
            new Item {Id = 1, Name = "Item1"},
            new Item {Id = 2, Name = "Item2"}
        };
    }
    
    // POST api/items
    [HttpPost]
    public IEnumerable<string> Create(List<Item> items)
    {
        return items.Select(i => i.Name).ToList();
    }

Verify

Run the app and verify the following:

  • A console appears indicating the server has started
  • Sending a GET request (via API testing tool of choice - e.g. Fiddler, Postman, etc.) gets the expected response
  • Sending a POST (e.g. simply POSTing the same data from the GET response) request gets the expected response
⚠️ **GitHub.com Fallback** ⚠️