Prepare Yourself for ASP.NET 5 - Part 4 (Application Startup)
In
Part 1,
Part 2 and
Part 3 of this series I discussed Less, Sass, NuGet, Npm, Bower, Grunt and
Gulp. In this part I am going to discuss the application "startup style" that
you will use in ASP.NET 5.
In an ASP.NET when the web server (IIS) starts your application, it invokes
Global.asax and code from event handlers such as Application_Start. So, things
that you wish to configure when an application starts go inside Global.asax.
ASP.NET MVC also makes use of App_Start folder and files such as RouteConfig.cs.
Application_Start event handler calls code from RouteConfig.cs to configure the
routing. In OWIN based applications this startup style is different. The new
style is also being used in ASP.NET 5.
Quick overview of OWIN and Katana
OWIN (Open Web Interface for .NET) introduced a different kind of application
startup style. ASP.NET 5 uses a startup style that closely resembles the OWIN
startup style. So, it is worthwhile to familiarize yourself with this style of
application startup.
I won't discuss OWIN in detail here. It would be suffice to say that OWIN is
a specification that describes how web development frameworks such as ASP.NET
should interact with the web servers. The goal of OWIN is to decouple web
applications from the web server by introducing an abstraction layer. Such an
abstraction enables you to run the same application on all the web servers that
support OWIN. Additionally, it simplifies the overall system because the
abstraction layer can provide a lightweight infrastructure to host the
applications. IIS provides a rich set of features to the web applications.
However, web applications may not need all these features. It might be
sufficient for them to have minimal HTTP processing capabilities. OWIN
compatible host can provide such a hosting environment to these applications.
Moreover, you can define a pipeline of modules that are used during the request
processing. An OWIN pipeline is a chain of OWIN compatible components through
which a request passes. The OWIN specification is a community initiative and
more details can be found at the owin.org website.
Katana is a set of components by Microsoft built using OWIN specifications.
Some of these components include Web API, ASP.NET Identity and SignalR.
A typical OWIN based system consists of four layers namely Application,
Middleware, Server and Host. The Application layer indicates your client
application. For example, a web site developed in ASP.NET MVC. The middleware
layer indicates a set of components built using OWIN specifications. These
components can be larger frameworks such as Web API or specialized components
such as ASP.NET Identity or SignalR. There can be more than one component in
this layer. The third layer is Server. A server listens to an incoming request
and performs the relevant network level tasks such as opening a socket. The
final layer is Host. This layer creates and manages a process for your
application. It also provides the overall environment for your application.
For the
rest of this article I will focus on the "startup style" mentioned earlier. I
also assume that you are familiar with Web API and self-hosting of Web API (If
you aren't familiar with these topics see ASP.NET MVC section under Categories
menu to read more).
Example - Web API self-hosting
Let's assume that you have a Web API that is hosted in an OWIN self host. The
Web API consists of a simple GET action - GetServerDateTime() - that returns
server date and time to the caller. This Web API looks like this:
namespace MyConsoleHost
{
public class MyWebApiController:ApiController
{
public string GetServerDateTime()
{
return DateTime.Now.ToString();
}
}
}
This We API is hosted by a console application. The code of the Web API host
is shown below:
using Microsoft.Owin.Hosting;
namespace MyConsoleHost
{
class Program
{
static void Main(string[] args)
{
string baseUrl = "http://localhost:8000";
WebApp.Start<Startup>(baseUrl);
Console.WriteLine("OWIN Host Started at " +
baseUrl);
Console.ReadLine();
}
}
}
The MyConsoleHost class plays the role of IIS here. It hosts and publishes
the Web API on the network. Notice the code shown in bold letters. WebApp class
resides in Microsoft.Owin.Hosting namespace and "starts" listening at the
specified URL. The Start() method is a generic method that specifies the startup
class. In this case class named Startup acts as the startup class but you can
name the class anything you wish.
The Startup class used above looks like this:
using Microsoft.Owin;
using Owin;
using System.Web.Http;
[assembly: OwinStartup(typeof(
MyConsoleHost.Startup))]
namespace MyConsoleHost
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultWebApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
app.UseWebApi(config);
}
}
}
The Startup class has a single method - Configuration(). This method is
important because it does the job of configuring the features you need. Although
the name of the class can be anything of your choice this method must be named
as Configure(). The Configure() method receives an instance of IAppBuilder.
Using this app instance you tell ASP.NET which all frameworks or OWIN middleware
you wish to use in your application. For example, in the above example
app.UserWebApi() tells the host that you intend to use Web API in your
application. The UseWebApi() accepts a configuration object. The configuration
object is used to configure the routing for the Web API. If you need additional
frameworks / middleware you would have mentioned them here. For example, if you
wish to use cookie authentication required by ASP.NET Identity in a web
application you would have written:
public void Configuration(IAppBuilder app)
{
...
...
CookieAuthenticationOptions options =
new CookieAuthenticationOptions();
options.AuthenticationType =
DefaultAuthenticationTypes.ApplicationCookie;
options.LoginPath = new PathString("/account/login");
app.UseCookieAuthentication(options);
}
What is important for you from ASP.NET 5 perspective is this style of
development. That is - creation of a startup class, writing the Configure()
method and telling ASP.NET about the frameworks/middleware you wish to utilize
(such as MVC, WebAPI, Identity and so on).
Notice that the name of the startup class is configurable through the
assembly level [OwinStartup] attribute. Most of the time Startup serves well but
just in case you wish to name it differently you can use [OwinStartup]
attribute.
[assembly: OwinStartup(typeof(MyConsoleHost.Startup))]
Above Web API can be consumed using a simple console application as shown
below:
class Program
{
static void Main(string[] args)
{
string baseUrl = "http://localhost:8000";
HttpClient client = new HttpClient();
HttpResponseMessage response =
client.GetAsync(baseUrl + "/api/MyWebApi").Result;
string serverDateTime =
response.Content.ReadAsStringAsync().Result;
Console.WriteLine("Server Date Time : " + serverDateTime);
Console.ReadLine();
}
}
The above code uses HttpClient class to invoke the Web API. The GetAsync()
method invokes the GET api method. The returned server date and time is then
outputted on the console.
That's it for this part! Will be back with the next installment soon.