In the example above, the same data type was stored in the session variable. Because there is no type checking of what gets stored, the problem of incompatible data types can also occur.
Code on one page:
Session["FollowUp"] = "true";
Code on a second page:
Session["FollowUp"] = 1;
Code on a third page:
Session["FollowUp"] = true;
When the bug manifests there will be an InvalidCastException thrown.
Usually this bug will NOT be picked up in testing. It is only when a user does some particular combination of page navigation (or opening a new browser window) that the bug manifests.
What Can We Do?
The First Quick Fix
The first and most simple thing we can do is make sure we never use string literals for session keys. Always use constants and so avoid simple typing mistakes.
private const string limit = "limit";...
Session[limit] = 27;...
Session[limit] = 32;
However, when constants are defined locally (e.g. at page level) we might still re-use the same key unintentionally.
A Better Quick Fix
Rather than define constants on each page, group all session key constants into a single location and provide documentation that will appear in Intellisense. The documentation should clearly indicate what the session variable is used for. For example, define a class just for the session keys:
public static class SessionKeys
{
/// <summary>
/// The maximum ...
/// </summary>
public const string Limit = "limit";
}
...
Session[SessionKeys.Limit] = 27;
When you need a new session variable, if you choose a name that has already been used you will know this when you add the constant to the SessionKeys class. You can see how it is currently being used and can determine if you should be using a different key.
However, we are still not ensuring consistency of data type.
A Much Better Way - Using a Facade
Only access the HttpSessionState from within one single static class in your application - the facade. There must be no direct access to the Session property from within code on pages or controls, and no direct access to HttpContext.Current.Session other than from within the facade
All session variables will be exposed as properties of the facade class.
This has the same advantages as using a single class for all the session keys, plus the following advantages:
Strong typing of what gets put into session variables.
No need for casting in code where session variables are used.
All the benefits of property setters to validate what gets put into session variables (more than just type).
All the benefits of property getters when accessing session variables. For example, initialising a variable the first time it is accessed.
An Example Session Facade Class
Here is an example class to implement the Session facade for an application called MyApplication.
Collapse
/// <summary>
/// MyApplicationSession provides a facade to the ASP.NET Session object.
/// All access to Session variables must be through this class.
/// </summary>
public static class MyApplicationSession
{
# region Private Constants
//---------------------------------------------------------------------
private const string userAuthorisation = "UserAuthorisation";
private const string teamManagementState = "TeamManagementState";
private const string startDate = "StartDate";
private const string endDate = "EndDate";
//---------------------------------------------------------------------
# endregion
# region Public Properties
//---------------------------------------------------------------------
/// <summary>
/// The Username is the domain name and username of the current user.
/// </summary>
public static string Username
{
get { return HttpContext.Current.User.Identity.Name; }
}
/// <summary>
/// UserAuthorisation contains the authorisation information for
/// the current user.
/// </summary>
public static UserAuthorisation UserAuthorisation
{
get
{
UserAuthorisation userAuth
= (UserAuthorisation)HttpContext.Current.Session[userAuthorisation];
// Check whether the UserAuthorisation has expired
if (
userAuth == null ||
(userAuth.Created.AddMinutes(
MyApplication.Settings.Caching.AuthorisationCache.CacheExpiryMinutes))
< DateTime.Now
)
{
userAuth = UserAuthorisation.GetUserAuthorisation(Username);
UserAuthorisation = userAuth;
}
return userAuth;
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!



