CHAPTER 26

image

Using OWIN

In the other chapters in this part of the book, I showed you how the Web API dispatch process works and demonstrated how to customize it. In this, the last chapter of this book, I describe one final change to the dispatch process: changing the hosting environment that runs the Web API application itself.

Image Caution  For this chapter, you must have an edition of Visual Studio 2013 that is capable of creating console applications. The free Visual Studio Express 2013 for Web edition that I have been using in all the previous chapters does not include this support. You will need one of the paid-for versions or Visual Studio Express 2013 for Windows Desktop, which can be downloaded for free from www.visualstudio.com.

Understanding OWIN

The Open Web Interface for .NET (OWIN) is a standard that defines an interface for .NET web applications. The idea behind OWIN is to break the link between web applications and the application server—or, put another way, to allow .NET web applications to be run outside of the traditional IIS environment.

Microsoft has embraced OWIN as a way to free ASP.NET from the System.Web assembly, which is part of the main .NET Framework and which means that ASP.NET releases are synchronized with major .NET Framework and Windows Server releases. It is in the early days for OWIN, but there is the potential for more flexibility in how .NET web applications are hosted as OWIN support in ASP.NET matures, beyond today’s choices of Azure and IIS running on Windows Server (although neither of these hosting options is going to go away).

Web API and SignalR are the first ASP.NET components to embrace OWIN and break away from the world of System.Web. This is why every Web API class and interface I have used in this book has been different from the ones you are familiar with in MVC framework development and why all of those types are contained in the System.Web.Http assembly, which is under the control of the ASP.NET development teams within Microsoft and not tied to the main .NET framework release schedule.

This is a short chapter because the range of OWIN hosting options is limited currently. The biggest limitation, however, is that only Web API and SignalR code can be run within OWIN. If you want to use the MVC framework to deliver static content, for example, then you will have to wait for MVC OWIN support, which will be introduced in MVC 6. Future editions of this book won’t need to contain warnings about the different MVC and Web API namespaces because everything will use the System.Web.Http types I have been using to create web services, but for the moment, OWIN support and the alternative hosting options it leads to are little more than a curiosity and not much use beyond experimentation and tinkering for most developers.

Image Note  If you become interested in OWIN, you will quickly come across references to Katana. Katana is a Microsoft package that allows OWIN applications to be hosted by IIS or Azure—or, put another way, provides a mapping between the traditional System.Web functionality and the OWIN specification. Katana doesn’t have any bearing on this book because, as I have demonstrated in previous chapters, Web API can already be hosted by IIS and Azure.

Creating a Self-hosted Web API Application

A self-hosted Web API application is a stand-alone process that receives and dispatches HTTP requests without relying on an application server. This means it is possible to embed Web API into other kinds of applications or to create small and simple Web API deployments that can run in constrained environments. In the sections that follow, I’ll show you how to create a simple self-hosted Web API application that relies on the OWIN specification.

Creating the Project

As I noted at the start of this chapter, you need an edition of Visual Studio that is able to create console applications. I will be using Visual Studio Express 2013 for Windows Desktop, but any of the paid-for editions will work as well.

To create the project, select File image New Project and select the Console Application from the Visual C# template section. (Visual Studio defaults to the Visual Basic template category, so be sure you get the C# template.) Set the name of the project to SelfHost and click the OK button. Visual Studio will create the project and add a class file to it called Program.cs.

Installing the Packages

Select Package Manager Console from the Visual Studio Tools image NuGet Package Manager menu and enter the following command:

Install-Package Microsoft.AspNet.WebApi.OwinSelfHost -Version 5.1.1

This will install the Microsoft OWIN classes for self-hosting and the Web API assemblies required to create web services.

Creating the Model and Repository

To keep the example simple, I will create a repository that maintains a collection of data objects in memory, just like I did in Chapter 10. I added a Models folder to the project and created the Product.cs file within it. Listing 26-1 shows the model class I defined.

Listing 26-1. The Contents of the Product.cs File

namespace SelfHost.Models {
    public class Product {
        public int ProductID { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
    }
}

This is a simplified version of the model class that I created for the SportsStore application in Chapter 5. Listing 26-2 shows the contents of the Repository.cs class file that I added to the Models folder.

Listing 26-2. The Contents of the Repository.cs File

using System.Collections.Generic;

namespace SelfHost.Models {
    public class Repository {
        private Dictionary<int, Product> data;
        private static Repository repo;

        static Repository() {
            repo = new Repository();
        }

        public static Repository Current {
            get { return repo; }
        }

        public Repository() {
            Product[] products = new Product[] {
                new Product {ProductID = 1, Name = "Kayak", Price = 275M },
                new Product {ProductID = 2, Name = "Lifejacket", Price = 48.95M },
                new Product {ProductID = 3, Name = "Soccer Ball", Price = 19.50M },
                new Product {ProductID = 4, Name = "Thinking Cap", Price = 16M },
            };

            data = new Dictionary<int, Product>();

            foreach (Product prod in products) {
                data.Add(prod.ProductID, prod);
            }
        }

        public IEnumerable<Product> Products {
            get { return data.Values; }
        }

        public Product GetProduct(int id) {
            return data[id];
        }

        public Product SaveProduct(Product newProduct) {
            newProduct.ProductID = data.Keys.Count + 1;
            return data[newProduct.ProductID] = newProduct;
        }

        public Product DeleteProduct(int id) {
            Product prod = data[id];
            if (prod != null) {
                data.Remove(id);
            }
            return prod;
        }
    }
}

My example repository populates an in-memory collection with Product objects and exposes them through a mix of properties and methods. Storing the data in memory means that the contents of the repository will be reset when the application is restarted. There is a static Current property that returns a shared instance of the Repository class, which I will use to obtain instances of the repository without having to implement dependency injection.

Defining the Configuration Classes

The configuration for OWIN-hosted applications is done through a class called Startup. I added a class file called Startup.cs to the example project and used it to define the class shown in Listing 26-3.

Listing 26-3. The Contents of the Startup.cs File

using Owin;
using System.Web.Http;

namespace SelfHost {
    public class Startup {

        public void Configuration(IAppBuilder appBuilder) {

            HttpConfiguration config = new HttpConfiguration();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            appBuilder.UseWebApi(config);
        }
    }
}

As you can see from the listing, the Startup class follows the same basic approach as the WebApiConfig.cs file that I have been relying on to configure IIS-hosted Web API applications in earlier chapters. The difference is that I have to create an instance of the HttpConfiguration class, which I described in Chapter 10, configure it for URL routing (as described in Chapters 20 and 21), and then call the UseWebApi method of the IAppBuilder parameter that is passed to the Configuration method.

The Startup class isn’t the only class that is required to self-host a Web API application. I also need to add code to the Program.cs file so that it will initialize OWIN and use the Startup class for configuration. Listing 26-4 shows the changes I made to the Program.cs file.

Listing 26-4. Defining the Self-hosting Application in the Program.cs File

using Microsoft.Owin.Hosting;
using System;

namespace SelfHost {

    class Program {

        static void Main(string[] args) {
            WebApp.Start<Startup>("http://localhost:5000/");
            Console.ReadLine();
        }
    }
}

The call to the WebApp.Start<Startup> method specifies that I want to use the Startup class to configure Web API, and the method argument specifies the URL that will be used to listen for requests. The call to Console.ReadLine prevents the console application exiting—if you omit this statement, then the application will terminate before the first HTTP request is received.

Creating the Web API Controller

The final step is to create a Web API controller to define the web service. I added a Controllers folder to the project and created within it a new class file called ProductsController.cs, the contents of which are shown in Listing 26-5.

Listing 26-5. The Contents of the ProductsController.cs File

using SelfHost.Models;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace SelfHost.Controllers {
    public class ProductsController : ApiController {

        public IEnumerable<Product> GetProducts() {
            return Repository.Current.Products;
        }

        public Product GetProduct(int id) {
            return Repository.Current.Products
                .Where(p => p.ProductID == id).FirstOrDefault();
        }

        public Product PostProduct(Product product) {
            return Repository.Current.SaveProduct(product);
        }

        public Product DeleteProduct(int id) {
            return Repository.Current.DeleteProduct(id);
        }
    }
}

Image Tip  There is no Visual Studio scaffolding support when creating self-hosted applications, and controllers have to be added by creating standard class files.

I have defined a RESTful controller that follows the same approach I used in Chapter 6. This controller lacks the features that I applied throughout Chapter 6, but it demonstrates the basic Web API mechanisms and exposes the contents of the repository to HTTP clients.

Testing the Self-hosted Web API Application

All that remains is to test the self-hosted application. I have not created a client application for the web service because that would require a separate non-Web API project, but it is easy to perform a test using Postman.

First, start the Web API application by selecting Start Debugging from the Visual Studio Debug menu. An empty console window will appear—do not close this because doing so will terminate the self-hosted application. Using Postman, send a GET request to the following URL:

http://localhost:5000/api/products

All of the Web API functionality I have described in this book is available in a self-hosted Web API application, and that includes, of course, URL routing. The URL route I defined in Listing 26-2 will map the request to the Products controller and the request verb, and the absence of data will target the GetProducts action method. Postman will display the following results, which correspond to the static data I defined in Listing 26-3:

[{"ProductID":1,"Name":"Kayak","Price":275.0},
 {"ProductID":2,"Name":"Lifejacket","Price":48.95},
 {"ProductID":3,"Name":"Soccer Ball","Price":19.50},
 {"ProductID":4,"Name":"Thinking Cap","Price":16.0}]

Summary

In this chapter, I gave you a brief overview of OWIN and the way it can be used to create self-hosted Web API applications that don’t depend on IIS or Azure. It is early days for OWIN, and it remains a curiosity for the moment; however, it is an area of investment for Microsoft, and subsequent versions of Web API—and the MVC framework—will build on this slim foundation.

And that is all I have to teach you about ASP.NET Web API and how it can be used to create HTTP web services. I started by creating a simple application and then took you on a comprehensive tour of the different components in Web API, showing you how they can be configured, customized, or replaced entirely to create the web services you need. I wish you every success in your Web API projects, and I can only hope that you have enjoyed reading this book as much as I enjoyed writing it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.69.199