亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ASP.NET 2.0中的輸出緩存

2019-11-18 16:48:11
字體:
來源:轉載
供稿:網友

Just about every asp.net application needs to keep track of data for a user's session. ASP.NET PRovides the HttpSessionState class to store session-state values. An instance of the HttpSessionState class for each HTTP request is accessible throughout your application using the static HttpContext.Current.Session property. Access to the same instance is made simpler on every Page and UserControl using the Session property of the Page or UserControl.

The HttpSessionState class provides a collection of key/value pairs, where the keys are of type String and the values are of type Object. This means that Session is extremely flexible and you can store just about any type of data in Session.

But (there is always a but) this flexibility does not come without a cost. The cost is the ease with which bugs can be introduced into your application. Many of the bugs that can be introduced will not be found by unit testing, and probably not by any form of structured testing. These bugs often only surface when the application has been deployed to the production environment. When they do surface it is often very difficult, if not impossible, to determine how they occured and be able to reproduce the bug. This means they are very expensive to fix.

This article presents a strategy to help prevent this type of bug. It uses a Design Pattern called a Facade, in that it wraps the very free interface provided by the HttpSessionState class (that can meet the requirements of any application) with a well designed and controlled interface that is purpose built for a specific application. If you are not familiar with Design Patterns or the Facade pattern, a quick internet search of "facade design pattern" will provide you with plenty of background. However, you do not have to understand design patterns in order to understand this article.

The example code shown in this article is written in C#, but the concepts are applicable to any .NET language.

What is the problem?
In this section of the article I will describe the problems with direct access to the HttpSessionState class, without the facade. I will describe the kinds of bugs that can be introduced.

The following shows the typical code written to access session-state variables.

// Save a session variable
Session["some string"] = anyOldObject;
// Read a session variable
DateTime startDate = (DateTime)Session["StartDate"];


The problems arise from the flexibile interface provided by HttpSessionState: the keys are just strings and the values are not strongly typed.

Using String Literals as Keys
If string literals are used as the keys, the string value of the key is not checked by the compiler. It is easy to create new session values by simple typing errors.

Session["received"] = 27;...
Session["recieved"] = 32;


In the code above, two separate session values have been saved.

Most bugs like this will be identified by unit testing – but not always. It may not always be apparent that the value has not changed as expected.

We can avoid this kind of bug by using constants:

private const string received = "received";...
Session[received] = 27;...
Session[received] = 32;


No Type Checking
There is no type checking of the values being stored in session variables. The compiler cannot check correctness of what is being stored.

Consider the following code:

Session["maxValue"] = 27;...
int maxValue = (int)Session["maxValue"];


Elsewhere the following code is used to update the value.

Session["maxValue"] = 56.7;


If the code to read the "maxValue" session variable into the maxValue int variable is executed again there will be an InvalidCastException thrown.

Most bugs like this will be identified by unit testing – but not always.

Re-using a Key Unintentionally
Even when we define constants on each page for the session keys, it is possible to unintentionally use the same key across pages. Consider the following example:

Code on one page:

private const string edit = "edit";...
Session[edit] = true;


Code on a second page, displayed after the first page:

private const string edit = "edit";...
if ((bool)Session[edit])
{
    ...
}


Code on a third, unrelated, page:

private const string edit = "edit";...
Session[edit] = false;


If the third page is displayed for some reason before the second page is displayed, the value may not be what was expected. The code will probably strill run, but the results will be wrong.

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.

At its worst, no one is aware that the bug has manifested, we may just end up modifying data to an unintended value.

Re-using a Key Unintentionally - again
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;
        }

        private set
        {
            HttpContext.Current.Session[userAuthorisation] = value;
        }
    }

    /// <summary>
    ///     TeamManagementState is used to store the current state of the
    ///     TeamManagement.aspx page.
    /// </summary>
    public static TeamManagementState TeamManagementState
    {
        get
        {
            return (TeamManagementState)HttpContext.Current.Session[teamManagementState];
        }

        set
        {
            HttpContext.Current.Session[teamManagementState] = value;
        }
    }

    /// <summary>
    ///     StartDate is the earliest date used to filter records.
    /// </summary>
    public static DateTime StartDate
    {
        get
        {
            if (HttpContext.Current.Session[startDate] == null)
                return DateTime.MinValue;
            else
                return (DateTime)HttpContext.Current.Session[startDate];
        }

        set
        {
            HttpContext.Current.Session[startDate] = value;
        }
    }

    /// <summary>
    ///     EndDate is the latest date used to filter records.
    /// </summary>
    public static DateTime EndDate
    {
        get
        {
            if (HttpContext.Current.Session[endDate] == null)
                return DateTime.MaxValue;
            else
                return (DateTime)HttpContext.Current.Session[endDate];
        }

        set
        {
            HttpContext.Current.Session[endDate] = value;
        }
    }
    //---------------------------------------------------------------------
    # endregion
}


The class demonstrates the use of property getters that can provide default values if a value has not been explicitly stored. For example, the StartDate property provides DateTime.MinValue as a default.

The property getter for the UserAuthorisation property provides a simple cache of the UserAuthorisation class instance, ensuring that the instance in the session variables is kept up to date. This property also shows the use of a private setter, so that the value in the session variable can only be set under the control of facade class.

The Username property demonstrates a value that may once have been stored as a session variable but is no longer stored this way.

The following code shows how a session variable can be accessed through the facade. Note that there is not need to do any casting in this code.

// Save a session variable
MyApplicationSession.StartDate = DateTime.Today.AddDays(-1);
// Read a session variable
DateTime startDate = MyApplicationSession.StartDate;


Additional Benefits
An additional benefit of the facade design pattern is that it hides the internal implemention from the rest of the application. Perhaps in the future you may decide to use another mechanism of implementing session-state, other than the built-in ASP.NET HttpSessionState class. You only need to change the internals of the facade - you do not need to change anything else in the rest of the application.

Summary
The use of a facade for HttpSessionState provides a much more robust way to access session variables. This is a very simple technique to implement, but with great benefit.


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
少妇高潮久久77777| 亚洲影视中文字幕| 亚洲韩国青草视频| 日韩精品中文字幕在线| 欧美日韩国产丝袜美女| 国产一区视频在线播放| 亚洲欧美精品中文字幕在线| 日韩成人在线视频网站| 亚洲国产精品va| 国产精品96久久久久久| 欧美在线激情网| 欧美成人午夜剧场免费观看| 日韩欧美国产黄色| 日本高清+成人网在线观看| 亚洲欧美日韩一区二区在线| 欧美久久精品一级黑人c片| 亚洲加勒比久久88色综合| 国产欧美日韩免费| 色偷偷偷综合中文字幕;dd| 欧美激情精品久久久久久| 国产成人av在线播放| 中文字幕亚洲自拍| 国产成人97精品免费看片| 555www成人网| 97精品国产97久久久久久春色| 亚洲桃花岛网站| 黑人巨大精品欧美一区二区| 国产精品你懂得| 亚洲国产欧美一区二区三区同亚洲| 自拍偷拍亚洲在线| 日韩精品免费综合视频在线播放| 国产精品成人一区二区| 欧美日韩999| 成人精品久久一区二区三区| 97免费中文视频在线观看| 97人洗澡人人免费公开视频碰碰碰| 成人黄色片在线| 日韩电影中文字幕| 欧美重口另类videos人妖| 亚洲乱码一区av黑人高潮| 久久综合久中文字幕青草| 亚洲第一免费播放区| 亚洲毛片在线看| 国产精品丝袜久久久久久不卡| 不用播放器成人网| 亚洲欧美制服中文字幕| 国产精品一区二区三| 97久久久免费福利网址| 91精品一区二区| 91免费观看网站| 久久免费视频观看| 亚洲人成毛片在线播放| 日韩有码在线播放| 午夜精品久久久久久久男人的天堂| 秋霞av国产精品一区| 亚洲欧美在线播放| 欧美精品九九久久| 久久国产精品偷| 欧美日韩性视频在线| 黄色一区二区在线| 91亚洲精品一区二区| 亚洲国产精品电影在线观看| 日韩精品中文字幕在线播放| 久久精品这里热有精品| 亚洲国产成人精品一区二区| 成人免费福利视频| 欧美激情中文字幕在线| 欧美wwwxxxx| 亚洲免费av网址| 成人亚洲激情网| 国产一区私人高清影院| 亚洲激情国产精品| 亚洲国产小视频在线观看| 欧美精品在线免费观看| 国产成人午夜视频网址| 97国产成人精品视频| 国产精品亚洲网站| 欧美日韩xxx| 欧美另类69精品久久久久9999| 精品日韩中文字幕| 欧美日韩福利在线观看| 成人免费淫片aa视频免费| 国产精品99久久久久久白浆小说| 日韩中文在线不卡| 中文字幕av一区二区三区谷原希美| 亚洲国产日韩欧美在线99| 在线视频欧美日韩| 欧美自拍视频在线| 成人亚洲综合色就1024| 国产亚洲欧美aaaa| 久久久久国产精品免费网站| 欧美精品做受xxx性少妇| 日韩av网址在线观看| 亚洲偷欧美偷国内偷| 91老司机精品视频| 色偷偷噜噜噜亚洲男人| 精品网站999www| 国产精品扒开腿做| 97在线看福利| 热久久美女精品天天吊色| 国产精品盗摄久久久| 精品调教chinesegay| 亚洲欧美综合区自拍另类| 韩国三级电影久久久久久| 亚洲xxx自由成熟| 国产精品爽黄69天堂a| 亚洲香蕉伊综合在人在线视看| 8x海外华人永久免费日韩内陆视频| 日日噜噜噜夜夜爽亚洲精品| 国产日韩在线视频| 欧美亚洲成人免费| 欧美中在线观看| 午夜精品视频网站| 久久久久久久久爱| 欧美亚洲激情视频| 国模gogo一区二区大胆私拍| 日韩成人在线播放| 国产日本欧美一区| 亚洲国产欧美在线成人app| 久久精品影视伊人网| 国产欧美日韩免费看aⅴ视频| 精品国产视频在线| 日韩欧美第一页| 国产一区二区欧美日韩| 久久久久久久久电影| 久久精品国产精品| 欧美巨猛xxxx猛交黑人97人| www.亚洲男人天堂| 91久久精品国产91性色| 日韩经典中文字幕在线观看| 国产精品小说在线| 成人写真视频福利网| 国产精品久久久久77777| 久久久天堂国产精品女人| 成人精品在线视频| 久久大大胆人体| 动漫精品一区二区| 欧美丰满片xxx777| 亚洲综合一区二区不卡| 国产精品视频资源| 中文字幕自拍vr一区二区三区| 亚洲性视频网址| 欧美成人午夜视频| 国产精品三级久久久久久电影| 日本久久久a级免费| 久久影视电视剧凤归四时歌| 九九视频这里只有精品| 91嫩草在线视频| 精品视频中文字幕| 欧美裸体男粗大视频在线观看| 日韩电影免费观看中文字幕| 国产成人涩涩涩视频在线观看| 欧美精品成人在线| 色yeye香蕉凹凸一区二区av| 国模精品一区二区三区色天香| 精品国产一区二区三区久久久狼| 亚洲精品999| 午夜精品蜜臀一区二区三区免费| 午夜精品一区二区三区视频免费看| 国产精品专区第二| 亚洲性av在线| 日本精品久久中文字幕佐佐木| 午夜精品福利在线观看| 亚洲免费av片|