Scenario
One of the ways of persisting values across
requests in MVC involves interacting with Session
, an instance of “HttpSessionStateBase
”.
It involves following steps:
- Store
data in
Session
against a key.
[HttpPost]
public ActionResult Index(Employee model)
{
Session["EmployeeID"] = model.EmployeeID;
Session["EmployeeName"] = model.EmployeeName;
Session["Title"] = model.Title;
return RedirectToAction("About");
}
- Retrieval
involves following steps:
- Check if value exists.
- Cast it to appropriate type.
public ActionResult About()
{
StringBuilder sb = new StringBuilder();
Int64 employeeID = 0;
if (Session["EmployeeID"] != null)
{
employeeID = Convert.ToInt64(Session["EmployeeID"]);
}
string employeeName = "";
if (Session["EmployeeName"] != null)
{
employeeName = Session["EmployeeName"].ToString();
}
string title = "";
if (Session["Title"] != null)
{
title = Session["Title"].ToString();
}
sb.Append("<div class='error'>
Following is the information entered in Home Page<br/></div>");
sb.Append("Employee ID : ").Append(employeeID.ToString()).Append("<br/>");
sb.Append("Employee Name : ").Append(employeeName).Append("<br/>");
sb.Append("Title : ").Append(title).Append("<br/>");
ViewBag.EmployeeInfo = sb.ToString();
return View();
}
So, storing and retrieving involves lot
of steps. We have to repeat these steps (in controller) whenever we need to
store or retrieve data from session.
Strongly
Typed Session in Controller Code
This tip provides a workaround in
which the code in controller can interact with session data in a strongly typed
manner. This also provides an alternate for “Extension Properties” which are
missing in C# (only extension methods exist).
The following code block
illustrates interacting with Session
(“State
” represents Session
. It is
explained later). The source code is attached
along with this tip. This sample code has been tested with Visual Studio
2010 for MVC3. The approach has been tested with Visual Studio 2012 for MVC4.
[HttpPost]
public ActionResult Index(Employee model)
{
State.EmployeeID = model.EmployeeID;
State.EmployeeName = model.EmployeeName;
State.Title = model.Title;
return RedirectToAction("About");
}
public ActionResult About()
{
StringBuilder sb = new StringBuilder();
sb.Append("<div class='error'>
Following is the information entered in Home Page<br/></div>");
sb.Append("Employee ID : ").Append(State.EmployeeID).Append("<br/>");
sb.Append("Employee Name : ").Append(State.EmployeeName).Append("<br/>");
sb.Append("Title : ").Append(State.Title).Append("<br/>");
ViewBag.EmployeeInfo = sb.ToString();
return View();
}
Steps
to Provide Strongly Typed Session in Controller
- Add
a folder “Infrastructure”
Add a class named “CustomState
” and import System.Web
and Ststem.Web.Mvc
namespaces. Add properties to CustomState
. This class
will access actual Session
to get/set data. These
properties will be available in controllers.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using StronglyTypedState.Models;
namespace StronglyTypedState.Infrastructure
{
public class CustomState
{
HttpSessionStateBase _session;
public CustomState(HttpSessionStateBase initializeSession)
{
_session = initializeSession;
}
public Int64 EmployeeID
{
get
{
if (_session[SessionKeys.EmployeeID.ToString()] == null)
_session[SessionKeys.EmployeeID.ToString()] = 0;
return Convert.ToInt64(_session[SessionKeys.EmployeeID.ToString()]);
}
set
{
_session[SessionKeys.EmployeeID.ToString()] = value;
}
}
public string EmployeeName
{
get
{
if (_session[SessionKeys.Employee_Name.ToString()] == null)
return String.Empty;
return _session[SessionKeys.Employee_Name.ToString()].ToString();
}
set
{
_session[SessionKeys.Employee_Name.ToString()] = value;
}
}
public string Title
{
get
{
if (_session[SessionKeys.Title.ToString()] == null)
return String.Empty;
return _session[SessionKeys.Title.ToString()].ToString();
}
set
{
_session[SessionKeys.Title.ToString()] = value;
}
}
}
}
- Declare
a
private
variable “_session
” of type “HttpSessionStateBase
” in this class and
initialize it in the constructor as shown.
- Add
a controller named
BaseController
in Controller folder and remove the method
“Index
” which Visual Studio adds by default.
- Define
a property “
State
” of type CustomState
in BaseController
. This is a read-only
property. The purpose of this is to get an instance of CustomState
class from
session
. If this does not exist, then a new instance is stored in session
and
it is returned. See the code block below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using StronglyTypedState.Infrastructure;
namespace StronglyTypedState.Controllers
{
public class BaseController : Controller
{
public CustomState State
{
get{
if (Session[SessionKeys.SessionState.ToString()] == null)
Session[SessionKeys.SessionState.ToString()] = new CustomState(Session);
return (CustomState)Session[SessionKeys.SessionState.ToString()];
}
}
}
}