Getting Started With ASP.Net Web API 2 : Day 9

Introduction

Before reading this article, I highly recommend reading the previous parts:

In this article we will learn about session state in Web API 2. The ASP.NET Web API does not support sessions and does not rely on System.Web. If we are running our API ASP.NET Web API within the ASP.NET runtime, we can enable the session state. The following are two ways to do it. 
  • Globally for the entire API
  • Locally, for specific routes only

To make the session global, we need to create the session behavior as SessionStateBehaviorin the Global.asax file.

  1. protected void Application_PostAuthorizeRequest()  
  2.         {  
  3.             HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);  
  4.         }  
Another way is per route. For that we need to create a route handle that implements IRequiredSessionState. This handle is attached to the Web API routes, that enable session state on request to those routes. 

The ASP.NET Web API 2 declares the routes in a static WebApiConfig class, against an instance of HttpConfiguration. And defines the Web API 2 routes against the System.Web.RouteCollection too. The method allows us to overload the MapHttpRoute. If the method is void, then it will return an instance of the newly declared route. If we declared the route directly using the System.Web.RouteCollection, the return would be a System.Web.Route object, where we can assign an IRouteHandler. 

HttpControllerRouteHandler, in the GetHttpHandler method, returns an instance of HttpControllerHandler, that is the entry point to the Web API pipeline. We use session on an IHttpHandler by making it implement an IRequiresSessionState interface. It will enable the session state for each route handler implementing that interface.

Prerequisites


There are the following things we need to use when developing a Web API 2 application for session state.

  • Visual Studio 2013
  • ASP.NET Web API 2 Template

Getting Started

In this section we will follow some important procedures and these are:

  • Create ASP.NET Web API
  • Add Web API 2 Controller
  • Add a class inside the model
  • Add a SessionHttpControllerRouteHandler class
  • Add SessionControllerHandler class

We need to use a basic procedure to enable session locally.

Step 1

Open the Visual Studio 2013 and click New Project.

Step 2

Select the ASP.NET Web Application and provide a nice name for the project.

NewProject

Step 3

Select the Web API template and click the OK button, by default it will choose MVC along with the Web API.

SelectTemplate

Step 4

Right-click on the Model folder and add a Student class to the model where the name fields are defined.

AddingClass

  1. namespace SessionState.Models  
  2. {  
  3.     public class NumberResult  
  4.     {  
  5.         public int NewValue { getset; }  
  6.         public int LastValue { getset; }  
  7.     }  
  8. }  
Step 5

Right-click on the Controller folder and select the Web API 2 empty Web API controller and provide a nice name. For this project I took NumberController.

AddingController

Step 6

Create a SessionHttpControllerRoteHandler class.
  1. namespace SessionState  
  2. {  
  3.     public class SessionHttpControllerRouteHandler : HttpControllerRouteHandler  
  4.     {  
  5.         protected override IHttpHandler GetHttpHandler(RequestContext requestContext)  
  6.         {  
  7.             return new SessionControllerHandler(requestContext.RouteData);  
  8.         }  
  9.     }  
  10. }  

This SessionHttpControllerRouteHandler class implements the HttpControllerRouteHandler. SessionHttpControllerRouteHandler is set as the RouteHandler on the created route.

Step 7

Create a SessionControllerHandler class.

  1. namespace SessionState  
  2. {  
  3.     public class SessionControllerHandler : HttpControllerHandler, IRequiresSessionState  
  4.     {  
  5.         public SessionControllerHandler(RouteData routeData)  
  6.             : base(routeData)  
  7.         { }  
  8.     }  
  9. }  
This is a custom SessionHttpControllerHandler class that implements IRequriesSessionState and a custom SessionHttpControllerRouteHandler that simply acts as a factory that returns SessionHttpControllerHandler.

Step 8

Register Web API routes against System.Web.RouteCollection.
  1. namespace SessionState  
  2. {  
  3.     public class RouteConfig  
  4.     {  
  5.         public static void RegisterRoutes(RouteCollection routes)  
  6.         {  
  7.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
  8.   
  9.             routes.MapHttpRoute(  
  10.                 name: "DefaultApi",  
  11.                 routeTemplate: "api/{controller}/{id}",  
  12.                 defaults: new { id = RouteParameter.Optional }  
  13.                 ).RouteHandler = new SessionHttpControllerRouteHandler();  
  14.   
  15.             routes.MapRoute(  
  16.                 name: "Default",  
  17.                 url: "{controller}/{action}/{id}",  
  18.                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }  
  19.             );  
  20.         }  
  21.     }  
  22. }  
Step 9

Enable the Session on All ASP.NET Web API Routes using a Reflection trick.
  1. namespace SessionState  
  2. {  
  3.     public static class WebApiConfig  
  4.     {  
  5.         public static void Register(HttpConfiguration config)  
  6.         {  
  7.             var httpControllerRouteHandler = typeof(HttpControllerRouteHandler).GetField("_instance",  
  8.                           BindingFlags.Static |  
  9.                           BindingFlags.NonPublic);  
  10.   
  11.             if (httpControllerRouteHandler != null)  
  12.             {  
  13.                 httpControllerRouteHandler.SetValue(null,  
  14.                     new Lazy<HttpControllerRouteHandler>(() => new SessionHttpControllerRouteHandler(), true));  
  15.             }  
  16.             config.MapHttpAttributeRoutes();  
  17.   
  18.             //config.Routes.MapHttpRoute(  
  19.             //    name: "DefaultApi",  
  20.             //    routeTemplate: "api/{controller}/{id}",  
  21.             //    defaults: new { id = RouteParameter.Optional }  
  22.             //);  
  23.         }  
  24.     }  
  25. }  
Step 10

A sample code ApiController that holds the session sate.
  1. namespace SessionState.Controllers  
  2. {  
  3.     public class NumberController : ApiController  
  4.     {  
  5.         public NumberResult get()  
  6.         {  
  7.             var newValue= new Random().Next(1,7);  
  8.             object context;  
  9.             if (Request.Properties.TryGetValue("MS_HttpContext"out context))  
  10.             {  
  11.                 var httpContext = context as HttpContextBase;  
  12.                 if (httpContext != null && httpContext.Session != null)  
  13.                 {  
  14.                     var lastValue = httpContext.Session["LastValue"as int?;  
  15.                     httpContext.Session["LastValue"] = newValue;  
  16.                     return new NumberResult  
  17.                     {  
  18.                         NewValue= newValue,  
  19.                         LastValue=lastValue??0  
  20.                     };  
  21.                 }  
  22.             }  
  23.             return new NumberResult { NewValue = newValue };  
  24.         }  
  25.     }  
  26. }  
Output

output

This will generate a random number every time.

Further Reading

<< Getting Started with ASP.NET Web API 2 : Day 8