Murach : How to work with session state and cookies
1. CHAPTER 9
How to work
with session state
and cookies
By : Eng. Mahmoud Hassouna
Email : M.hassuna2@gmail.com
2. How ASP.NET MVC handles
state
The data that a web app maintains for a user,
such as variables, is the state of
that app. However, HTTP is a stateless protocol. This
means that HTTP doesn’t
keep track of an app’s state between round trips.
Rather, once a browser makes a
request and receives a response, the app
terminates and its state is lost.
6. Description
State refers to the current status of the properties, variables,
and other data maintained by an app for a single user.
HTTP is a stateless protocol. That means that it doesn’t keep
track of state between round trips. Once a browser makes a
request and receives a response, the app terminates and its
state is lost.
ASP.NET Core MVC provides several ways to maintain the state
of a web app. A cookie is a key/value pair passed to the user in
an HTTP response and passed back to the server with each
subsequent HTTP request. Session state works by having the
server store the session data for a user and by
using a cookie to associate the user’s web browser with the
correct session data.
7. How to work with session
state
Session state allows you to store data that you
want to persist across multiple
HTTP requests. This feature is extremely useful and
commonly used by many
types of web apps such as shopping cart apps.
8. The ConfigureServices() method
in the Startup.cs file
public void ConfigureServices(IServiceCollection services)
{
...
// must be called before AddControllersWithViews()
services.AddMemoryCache();
services.AddSession();
services.AddControllersWithViews();
...
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
9. •
# The Configure() method in the
Startup.cs file
public void Configure(IAppBuilder app, IHostingEnvironment env)
{
...
// must be called before UseEndpoints()
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
...
}
10. services.AddSession(options =>
{
// change idle timeout to 5 minutes -
default is 20 minutes
options.IdleTimeout =
TimeSpan.FromSeconds(60 * 5);
options.Cookie.HttpOnly = false; //
default is true
options.Cookie.IsEssential = true; //
default is false
});
11. Description
By default, session state is not
enabled. To enable it, you can add
code to the ConfigureServices() and
Configure() methods in the Startup.cs
file that calls the AddMemoryCache(),
AddSession(), and UseSession()
methods in the correct sequence.
To change the default settings for
session state, you can use a lambda
expression to pass a SessionOptions
object to the AddSession() method.
12. Methods of the ISession interface
that set, get, and remove items
13. A using directive for session state in a
controller
using Microsoft.AspNetCore.Http;
An action method that gets and sets a
session state value
public ViewResult Index() {
int num = HttpContext.Session.GetInt32("num");
num += 1;
HttpContext.Session.SetInt32("num", num);
return View();
}
14. A using directive for session state in a
view
@using Microsoft.AspNetCore.Http
A Razor code block that gets a session
state value
@{
int num = Context.Session.GetInt32("num");
}
A Razor expression that gets a session
state value
<div>@Context.Session.GetInt32("num")</div>
15. Description
The Http Context class has a property named Session that
implements IS ession and thus provides methods for setting, getting,
and removing items in session state.
To enable all the functionality of the Session property, you must
import the Microsoft.AspNetCore.Http namespace.
A controller has an Http Context property that has a data type of
Http Context.
A view has a Context property that has a data type of HttpContext.
In ASP.NET Core MVC, session state can only store int and string
values. However, you can extend session state so it can store more
complex types as shown in the next figure.
16. How to add the New ton soft JSON
Nu Get package to your app
Use the Tools--NuGet Package Manager--Manage NuGet Packages
for Solutioncommand to open the NuGet Package Manager.
Click the Browse link.
Type “Microsoft.AspNetCore.Mvc.NewtonsoftJson” in the search
box.
Click on the appropriate package from the list that appears in the
left-hand panel.
In the right-hand panel, check the project name, select the version
that matches the version of .NET Core you’re running, and click
Install.
Review the Preview Changes dialog that comes up and click OK.
Review the License Acceptance dialog that comes up and click I
Accept.
17. How to configure your app to use
the Newtonsoft JSON library
public void ConfigureServices(IServiceCollection
services) {
...
services.AddMemoryCache();
services.AddSession();
services.AddControllersWithViews().AddNewtonsoft
Json();
...
}
18. A using directive that imports the Newtonsoft JSON
library
using Newtonsoft.Json;
Two static methods of the JsonConvert class
19. Code in an action method that sets a Team
object in session state
Team team = new Team { TeamID = "sea", Name =
"Seattle Seahawks" };
string teamJson = JsonConvert.SerializeObject(team);
HttpContext.Session.SetString("team", teamJSON);
Code in an action method that gets a Team
object from session state
string teamJson = HttpContext.Session.GetString("team");
Team team =
JsonConvert.DeserializeObject<Team>(teamJson);
20. Description
•JSON (JavaScript Object Notation) is a data
format that facilitates the transfer of data.
To serialize .NET objects to JSON strings and back
again, you can use the open-source Newtonsoft
Json.NET library.
You can use the JsonIgnore attribute of the
Newtonsoft.Json namespace to mark properties in
an object that you don’t want to serialize.
21. Two extension methods for the ISession
interface
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
public static class SessionExtensions
{
public static void SetObject<T>(this ISession session,
string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T GetObject<T>(this ISession session, string key)
{
var valueJson = session.GetString(key);
if (string.IsNullOrEmpty(value)) {
return default(T);
}
else {
return JsonConvert.DeserializeObject<T>(valueJson);
}
}
}
22. Code that uses the extension
methods towork with a single
In a controller
var team = HttpContext.Session.GetObject<Team>("team") ??
newTeam(); team.Name = "Seattle Seahawks";
HttpContext.Session.SetObject("team", team);
In a view
@{
var team = Context.Session.GetObject<Team>("team");
}
23. Code that uses the extension methods
to work with a list of teams
In a controller
var teams =
HttpContext.Session.GetObject<List<Team>>("teams") ??
new List<Team>();
teams.Add(new Team { TeamID = "gb", Name = "Green Bay
Packers" });
HttpContext.Session.SetObject("teams", teams);
In a view
@{
var teams =
Context.Session.GetObject<List<Team>>("teams");
}
24. Description
To make it easier to store objects in
session state, you can add
extension methods to the ISession
interface.
25. A wrapper class that encapsulates the
code for working with session state
26. Code that uses the wrapper class
to work with a list of teams
27. Description
To make it easier to work with
session state in your app, you can
create a wrapper class that
encapsulates the using directives,
method calls, and string keys in one
place.
A wrapper class can call extension
methods from the ISession interface
like the ones shown in the previous
figure.
28. The NFL Teams 3.0 app
The next few topics present a version of
the NFL Teams app that keeps track of a
user’s favorite teams in session state. Since
this app updates the NFL Teams app that
was presented in chapter 8, this chapter
only presents code that is new or
changed. If you haven’t read chapter 8
yet, you should at least review that
chapter before you continue.
32. Description
This version of the NFL Teams app enhances the
apps presented in chapter 8. It allows you to add a
team to your favorites and view your favorite
teams.
38. Description
The layout checks whether TempData stores
a message. If so, it displays that message.
The layout checks whether the current
page is the Favorites page. If not, it displays
a link to the Favorites page, gets the
number of favorite teams from session state,
and displays that number in a Bootstrap
badge.
39. Some code from the
Home/Index view
<div class="col-sm-9">
<ul class="list-inline">
@foreach (Team team in Model.Teams)
{
<li class="list-inline-item">
<a asp-action="Details" asp-route-id="@team.TeamID">
<img src="~/images/@team.LogoImage" alt="@team.Name"
title="@team.Name | @team.Conference.Name
@team.Division.Name" />
</a>
</li>
}
</ul>
</div>
40. Some code from theHome
/Details view
<li class="list-group-item">
<form asp-action="Add" method="post">
<a asp-action="Index" class="btn btn-primary"
asp-route-activeConf="@Model.ActiveConf"
asp-route-activeDiv="@Model.ActiveDiv">
Return to Home Page</a>
<button type="submit" class="btn btn-primary">
Add to Favorites
</button>
<input type="hidden" asp-for="Team.TeamID" />
</form>
</li>
41. Description
The Home/Index view displays the images for the teams as links.
The Home/Details view includes an “Add to Favorites” button
that uses a <form> element to post the team ID to the Add()
action method.
The Home/Details view includes a “Return to Home Page” link
that’s styled as a button. This link returns to the Home page with
the active conference and division selected.
42.
43. Description
The Favorites controller has two action methods
.
The Index() action method is called when a user clicks the My
Favorite Teams link. This action method retrieves data from session
state and transfers it to the view for display.
The Delete() action method is called when a user clicks the Clear
Favorites button on the Favorites page. This action method
removes the favorite teams from session state and redirects the
user to the Home page using data from session state.
44.
45. Description
The Favorites/Index view displays information
about the teams that users have added to their
favorites. In addition, it includes a button and a
link that has been styled as a button.
The “Clear Favorites” button uses a <form>
element to call the Delete() action method of the
Favorites controller with a POST request.
The “Return to Home Page” link gets the Home
page with the active conference and division
selected.
46. How to work with cookies
A cookie is a key/value pair that’s stored in the user’s browser
or on the user’s disk. A web app sends a cookie to a browser
via an HTTP response. Then,
each time the browser sends an HTTP request to the server, it
sends that cookie back.
A session cookie is stored in the browser’s memory and exists
only for the
duration of the browser session. A persistent cookie, on the other
hand, is stored on the user’s disk and is retained until the
cookie’s expiration date, or until the
user clears the cookie.
47. How to work with
persistent cookies
The second table presents some of the properties of the
CookieOptions class.
This class allows you to change some of the settings of a cookie
and is stored in the Microsoft.AspNetCore.Http namespace.
As a result, to use it, you need to include a using directive like
the one shown in the first code example below this table.
48. To set a persistent cookie, you need to set the Expires property
of the CookieOptions class. To do that, you create a
CookieOptions object, set its Expires property to a DateTime
value, and
include the CookieOptions object when you
create a cookie. This is shown by the last example in this figure. To
start, it creates a new
CookieOptions object with an Expires property of 30 days from
the current date and time. Then, it passes that object to the
Append() method as the third argument.
50. Code that sets a session cookie
Response.Cookies.Append("username",
"Grace");
Code that deletes a cookie
Response.Cookies.Delete("username");
Code that gets a cookie
string value =
Request.Cookies["username"]; //
brackets, not parentheses
51. Some of the properties of
the Cookie Options class
52. A using directive that’s necessary to work with the
Cookie Options class
using Microsoft.AspNetCore.Http;
Code that sets a persistent cookie
var options = new CookieOptions { Expires =
DateTime.Now.AddDays(30) };
Response.Cookies.Append("username", "Grace",
options);
53. Description
A cookie is a key/value pair that’s stored in the
user’s browser or on the user’s disk.
A web app sends a cookie to a browser via an HTTP
response. Then, each time the browser sends an
HTTP request to the server, it sends that cookie back.
A session cookie is stored in the browser’s memory
and exists only for the duration of the browser
session.
A persistent cookie is stored on the user’s disk and is
retained until the cookie’s expiration date or until the
user clears the cookie.
54. The NFL Teams 4.0 app
Now that you know how to work with cookies, you’re ready to
see a version of the NFL Teams app after it has been updated
to
store the IDs of the user’s favorite teams in a persistent cookie.
That way, the app
“remembers” its users’ favorite teams, even when its users close
their browsers and return to this app later.
55. The updated session class
Figure 9-15 shows the NFLSession class. This class works like the
NFLSession class shown earlier in this chapter, but its
GetMyTeamCount() method returns a nullable int type, not a
regular int type. This makes it possible to check whether a session
state
object already exists or whether you should initialize a new
object by getting data from cookies.
56. The NFL Cookies class
using Microsoft.AspNetCore.Http;
public class NFLCookies
{
private const string MyTeams = "myteams";
private const string Delimiter = "-";
private IRequestCookieCollection requestCookies { get; set; }
private IResponseCookies responseCookies { get; set; }
public NFLCookies(IRequestCookieCollection cookies) {
requestCookies = cookies;
}
public NFLCookies(IResponseCookies cookies) {
responseCookies = cookies;
}
57. The NFL Cookies class
public void SetMyTeamIds(List<Team> myteams){
List<string> ids = myteams.Select(t => t.TeamID).ToList();
string idsString = String.Join(Delimiter, ids);
CookieOptions options = new CookieOptions {
Expires = DateTime.Now.AddDays(30)
};
RemoveMyTeamIds(); // delete old cookie first
responseCookies.Append(MyTeams, idsString, options);
}
58. The NFL Cookies class
public string[] GetMyTeamsIds() {
string cookie =
requestCookies[MyTeams];
if (string.IsNullOrEmpty(cookie))
return new string[] { }; // empty
string array else
return cookie.Split(Delimiter);
}
public void RemoveMyTeamIds(){
responseCookies.Delete(MyTeams); } }
60. Description
This app stores the IDs of the user’s favorite teams in a persistent
cookie.
The NFLCookies class has an overloaded constructor that can
accept the Cookies
collection from the Request object or from the Response object.
The GetMyTeamCount() method of the NFLSession class now
returns a nullable int.
63. Description
The Index() action method uses the cookie
collection of the Request object to get the user’s
favorite teams from a persistent cookie. Then, it
stores them in session state.
The Add() action method uses the cookie
collection of the Response object to update the
data in the persistent cookie. But first, it updates
session state.
64. The updated Favorites
controller
This action method works like the Delete() action method presented
in figure
9-12. However, it also removes the persistent cookie that holds the
IDs of the
user’s favorite teams after it removes those teams from session state.
To delete the cookie, the code creates a new NFLCookies object
and passes
it the Cookies collection of the controller’s Response object. Then,
this code
calls the RemoveMyTeamIds() method of the NFLCookies object.
66. Description
The Delete() action method of the Favorites
controller removes the persistent
cookie that stores the IDs of the favorite teams.
But first, it removes the favorite teams from session
state.