1. 程式人生 > 實用技巧 >HttpContext.Current.Items用途

HttpContext.Current.Items用途

HTTP是一個無狀態的協議。每次的請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求是無直接關係的,它不會受前面的請求應答情況直接影響,也不會直接影響後面的請求應答情況。

而實際上,我們的系統往往要支援使用者在客戶端瀏覽器和服務端之間的多次請求共用相同的資料(狀態),比如使用者的登陸賬號資訊。於是乎,ASP.NET提供了很多變數來管理狀態:比如application state,session state,view state等。

HttpContext物件只針對一個單一的http請求。這個類的屬性還有Request物件、Response物件、Session物件等。這裡要說的是HttpContext類的Items(屬性) 集合,它包含了key-value形式的雜湊表物件。

首先,我們看HttpContext.Current.Items的用途,它只作用於單獨的一個使用者請求(HttpContext.Current.Items valid for a single HTTPRequest)。完成這個請求,伺服器資訊傳回瀏覽器的時候,這個Item集合將丟失。而Session物件是針對使用者的本次會話,也就是作用 於多個使用者請求,在Session失效後才丟失其中的資訊。

既然HttpContext.Current.Items的生命週期如此之短,那在什麼情況下可以加以利用呢。這裡指出,HttpContext.Current.Items 可以在 HttpModule 和 HTTPHandler 之間共享資料時使用,因為每次使用者請求都要通過HTTP 執行時管道HttpModule 、HTTPHandler 。當你實現IHttpMoudle的方法來通過HttpMoudle向用戶請求傳遞資訊。你可以用HttpContext.Current.Items 在不同請求頁,不同的HttpModule中傳輸資料,但是一旦請求結束,資料回發,這個集合中的資料將自己丟失。如下圖所示:

另外,當服務端頁面跳轉(Server.Execute/Server.Transfer)時,我們可以使用HttpContext.Current.Items在兩個表單之間傳遞資料。

/*** WebForm1: ***/
private void Page_Load(object sender, System.EventArgs e)
{
    ArrayList list = new ArrayList(4);
    list.Add("This list ");
    list.Add("is for ");
    list.Add("WebForm2 ");
    list.Add("to see. ");
    Context.Items["WebForm1List"] = list;
    Server.Transfer("WebForm2.aspx");
}
/*** 對於WebForm2: ***/
private void Page_Load(object sender, System.EventArgs e)
{
    ArrayList list = Context.Items["WebForm1List"] as ArrayList;

    foreach(string s in list)
    {
        Response.Write(s);
    }
}

很顯然,如果把Server.Transfer改為Response.Redirect的時候,由於是不同的Http請求,在新的頁面裡是無法獲取到HttpContext.Current.Items裡的資料的。這時會報System.NullReferenceException: 未將物件引用設定到物件的例項。

快取幫助類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace HS.Core.Cache
{    
    /// <summary>
    /// 快取幫助
    /// </summary>
    public class CacheHelper
    {
        #region 以下幾個方法從HttpContext.Items快取頁面資料,適合頁面生命週期,頁面載入後就被移除,而非HttpContext.Cache在整個應用程式都有效
        //如果上下文HttpContext.Current.Items裡沒有,則取資料然後加入Items,在頁面生命週期內有效
        public static F GetItem<F>(string name, Func<F> getRealData)
        {
            if (HttpContext.Current == null) 
                return getRealData();

            var httpContextItems = HttpContext.Current.Items;
            if (httpContextItems.Contains(name))
            {
                return (F)httpContextItems[name];
            }
            else
            {
                var data = getRealData();
                if (data != null)
                    httpContextItems[name] = data;
                return data;
            }
        }
        
        public static F GetItem<F>() where F : new()
        {
            return GetItem<F>(typeof(F).ToString(), () => new F());
        }

        public static F GetItem<F>(Func<F> getRealData)
        {
            return GetItem<F>(typeof(F).ToString(), getRealData);
        }
        #endregion

    }
}

***********轉摘:https://www.jianshu.com/p/b5b29dee28a9