[ASP.net] Cookie怎麼寫就怎麼讀
最近翻閱ASP.net 問題解決[實戰] 此本書的3-89頁介紹到
若想要依使用者的選擇來動態切換Master Page的話,可以先將使用者的選擇寫到Cookie中,然後再(Page_PreInit事件)依前述(Page.MasterPageFile=網路路徑)來切換Master Page
例如:
Response.Cookies.Add("MasterPage", "~/masterPage/MyMasterPage.master");
以上的程式碼讓我覺得詭異的情況下,自行Try了一下,果然Cookie不是這樣寫的
正確寫法:
asp.net,cookie,写cookie,取cookie、Asp.Net -Cookie讀取中文變亂碼的解決方法
也因為翻了幾篇文章,重新認識Cookie,剛好有空有心情
就來測試一下
1. 如果輸出HttpCookie物件的單值,讀取時卻以多值的方式讀回來,或
2. 輸出HttpCookie物件的多值,讀取時卻以單值的方式讀回來的情況會怎樣?
Case 1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class B : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//產生一個Cookie
HttpCookie cookie = new HttpCookie("test");
//設定單值
cookie.Value = Server.UrlEncode("Hello!!世界");
//設定過期日
cookie.Expires = DateTime.Now.AddDays(2);
//寫到用戶端
Response.Cookies.Add(cookie);
}
}
//讀取cookie(以多值的方式)
protected void btn_test_Click(object sender, EventArgs e)
{
HttpCookie cookie = Request.Cookies["test"];
foreach (string value in cookie.Values)
{
Response.Write("Null?"+(value==null)+"<br/>");/*順便測試看看是否為null還是空字串*/
Response.Write("空字串?"+(value=="")+"<br/>");
Response.Write("foreach迴圈中撈出Request.Cookies['test']所有的Value:" + Server.UrlDecode(value)+"<hr/>");
}
Response.Write("Null?"+(cookie["test"]==null)+"<br/>");
Response.Write("空字串?" + (cookie["test"]=="")+"<br/>");
Response.Write("cookie['test'](HttpCookie物件裡索引名為test的值):"+Server.UrlDecode(cookie["test"])+"<hr/>");
}
}
執行結果:
第一次網頁執行
按下Button
以多值方式讀取回來的值都是空值null
接著我把IE9中所有的暫存和Cookie刪除
再改寫一下程式碼(這次讀取改以單值的方式),並重新執行按下Button
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//產生一個Cookie
HttpCookie cookie = new HttpCookie("test");
//設定單值
cookie.Value = Server.UrlEncode("Hello!!世界");
//設定過期日
cookie.Expires = DateTime.Now.AddDays(2);
//寫到用戶端
Response.Cookies.Add(cookie);
}
}
//讀取cookie(這次改以單值的方式)
protected void btn_test_Click(object sender, EventArgs e)
{
HttpCookie cookie = Request.Cookies["test"];
Response.Write("Null?"+(cookie.Value==null)+"<br/>");
Response.Write("空字串?" + (cookie.Value=="")+"<br/>");
Response.Write("顯示cookie.Value的值:" + Server.UrlDecode(cookie.Value) + "<hr/>");
}
執行結果:
這次就有值了
Case 2 : (輸出HttpCookie物件的多值,讀取時卻以單值的方式讀回來的情況)
程式碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class B : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//產生一個Cookie物件
HttpCookie cookie = new HttpCookie("test");
//設定多值(這裡只能以字串的方式設定)
cookie.Values.Add("1", "Hello");
cookie.Values.Add("2", Server.UrlEncode("世界!!"));
//設定過期日(這裡只能針對全體cookie物件設定過期日)
cookie.Expires = DateTime.Now.AddDays(2);
//寫到用戶端
Response.Cookies.Add(cookie);
}
}
//讀取cookie(以單值的方式)
protected void btn_test_Click(object sender, EventArgs e)
{
HttpCookie cookie = Request.Cookies["test"];
Response.Write("Null?"+(cookie.Value==null)+"<br/>");
Response.Write("空字串?" + (cookie.Value=="")+"<br/>");
Response.Write("顯示cookie.Value的值:" + Server.UrlDecode(cookie.Value) + "<hr/>");
}
}
一樣我事先把IE9的暫存和Cookie刪除並關閉所有IE9視窗
然後才執行程式:
第一次網頁執行
按下Button
所以用多值的方式寫出去,以單值的方式讀回來的Value
就會像以上的結果,是用Key=Value&Key=Value的值回傳回來(不是null)
所以多值輸出的正確讀取方式應該如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class B : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//產生一個Cookie物件
HttpCookie cookie = new HttpCookie("test");
//設定多值(這裡只能以字串的方式設定)
cookie.Values.Add("1", "Hello");
cookie.Values.Add("2", Server.UrlEncode("世界!!"));
//設定過期日(這裡只能針對全體cookie物件設定過期日)
cookie.Expires = DateTime.Now.AddDays(2);
//寫到用戶端
Response.Cookies.Add(cookie);
}
}
//讀取cookie(改以多值的方式)
protected void btn_test_Click(object sender, EventArgs e)
{
HttpCookie cookie = Request.Cookies["test"];
Response.Write("顯示cookie物件裡的值1:" + cookie.Values["1"] + "<hr/>");
Response.Write("顯示cookie物件裡的值2:" + Server.UrlDecode(cookie.Values["2"]) + "<hr/>");
}
}
2011.12.15追記 使用cookie["1"]、cookie["2"]來讀取應該也行
執行結果:
接下來解決幾個疑惑
HttpCookie cookie = new HttpCookie("test")
cookie.Value等於cookie["test"]???
答案是No~
請看程式碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class B : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//產生一個Cookie物件
HttpCookie cookie = new HttpCookie("test");
//設定單值(這裡只能以字串的方式設定)
cookie.Value = "Hello World!!";
//設定過期日(這裡只能針對全體cookie物件設定過期日)
cookie.Expires = DateTime.Now.AddDays(2);
//寫到用戶端
Response.Cookies.Add(cookie);
}
}
//嘗試讀取cookie
protected void btn_test_Click(object sender, EventArgs e)
{
HttpCookie cookie = Request.Cookies["test"];
Response.Write("cookie['test']為Null?" + (cookie["test"]==null) + "<hr/>");
Response.Write("cookie['test']為空字串?:" + (cookie["test"]=="") + "<hr/>");
Response.Write("顯示cookie['test']的值:" + cookie["test"] + "<hr/>");
Response.Write("顯示cookie物件的單值(cookie.Value):" + cookie.Value + "<hr/>");
}
}
執行結果:
第一次執行畫面
按下Button
所以正確應該說cookie["test"]其實就相當於Request.Cookies["test"]["test"]
請見以下代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class B : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//產生一個Cookie物件
HttpCookie cookie = new HttpCookie("test");
//設定多值(這裡只能以字串的方式設定)
cookie.Values.Add("test", "Hi");
cookie.Values.Add("test2", "shadow");
//設定過期日(這裡只能針對全體cookie物件設定過期日)
cookie.Expires = DateTime.Now.AddDays(2);
//寫到用戶端
Response.Cookies.Add(cookie);
}
}
//嘗試讀取cookie
protected void btn_test_Click(object sender, EventArgs e)
{
Response.Write(Request.Cookies["test"]["test"]);
}
}
按下按鈕後的執行結果:
第二個問題
如果不設定過期日,預設Cookie什麼時候會過期?
我先把IE9的暫存和Cookie都刪除後,嘗試再度輸出Cookie
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class B : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
}
protected void btn_test_Click(object sender, EventArgs e)
{
//產生一個Cookie物件
HttpCookie cookie = new HttpCookie("test");
//設定多值(這裡只能以字串的方式設定)
cookie.Values.Add("test", "Hi");
cookie.Values.Add("test2", "shadow");
//不設定過期日
//寫到用戶端
Response.Cookies.Add(cookie);
}
}
執行:
按下Button寫出Cookie
但這次不做瀏覽器的清除Cookie動作我就直接關閉瀏覽器
並改寫程式碼嘗試讀取Cookie
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class B : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Response.Write("Request.Cookies['test']['test']為Null?"+(Request.Cookies["test"]["test"]==null)+"<hr/>");
Response.Write("Request.Cookies['test']['test']為空字串?" + (Request.Cookies["test"]["test"] == "") + "<hr/>");
Response.Write("Request.Cookies['test']['test']的值為:" + Request.Cookies["test"]["test"] + "<hr/>");
}
}
protected void btn_test_Click(object sender, EventArgs e)
{
}
}
執行結果:
直接NullReferenceException,沒有Request.Cookies["test"]["test"]這東西
也就是說Cookie物件沒給過期值,預設當瀏覽器關閉後就跟著消失
最後再順便看看寫出Cookie的單值和多值會以什麼形式儲存在IE9上
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class B : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//單值
HttpCookie cookie = new HttpCookie("test");
cookie.Value = "testValue值";
cookie.Expires = DateTime.Now.AddDays(2);
Response.Cookies.Add(cookie);
//多值
HttpCookie cookies = new HttpCookie("test2");
cookies.Values.Add("1", "Hi");
cookies.Values.Add("2測試", "測試值");
cookies.Expires = DateTime.Now.AddDays(2);
Response.Cookies.Add(cookies);
}
}
protected void btn_test_Click(object sender, EventArgs e)
{
}
}
先執行程式輸出Cookie到用戶端:
再嘗試在瀏覽器中尋找剛剛輸出的Cookie
把此檔案打開來
2011.12.15 追記,剛剛試著把寫入的Cookie沒做UrlEncode、UrlDecode直接活生生地讀取出來,中文沒有變亂碼,推測應該是IE9的關係。
2011.12.16 追記,睡前想到要模擬一個情況
如果單值和多值都同時設定的話,會?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class B : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//單值
HttpCookie cookie = new HttpCookie("2011.12.16");
cookie.Value = "testValue值";
//針對同一個物件寫入多值
cookie.Values.Add("1", "Hi");
cookie.Values.Add("2測試", "測試值");
cookie.Expires = DateTime.Now.AddDays(2);
Response.Cookies.Add(cookie);
}
}
//讀取Cookie,並顯示
protected void btn_test_Click(object sender, EventArgs e)
{
HttpCookie cookie = Request.Cookies["2011.12.16"];
Response.Write("單值:"+cookie.Value+"<hr/>");
Response.Write("以下為多值<br/>");
Response.Write(cookie["1"] + "<br/>");
Response.Write(cookie["2測試"] + "<br/>");
}
}
按下Button後的執行結果:
所以還是別混著使用為妙
衍伸閱讀:[ASP.net] 透過JavaScript 建立.刪除.讀取Cookie解決方案,包含C#讀取解決中文亂碼問題..