我想在ASP.NET MVC裡用foreach列舉所有Cookie,HttpRequestBase.Cookies是不二人選。Cookies屬性的型別為HttpCookieCollection,既然是HttpCookieCollection,foreach拿到的應該就是HttpCookie吧?很自以為是地寫好以下程式準備收工:
public ActionResult TestCookies()
{
var req = this.HttpContext.Request;
StringBuilder sb = new StringBuilder();
foreach (HttpCookie cookie in req.Cookies)
{
sb.AppendFormat("{0}: {1}\n", cookie.Name, cookie.Value);
}
return Content(sb.ToString());
}
不料,程式噴出以下錯誤:
無法將類型 'System.String' 的物件轉換為類型 'System.Web.HttpCookie'。
描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外狀況詳細資訊: System.InvalidCastException: 無法將類型 'System.String' 的物件轉換為類型 'System.Web.HttpCookie'。
原始程式錯誤:
行 63: var req = this.HttpContext.Request;
行 64: StringBuilder sb = new StringBuilder();
行 65: foreach (HttpCookie cookie in req.Cookies)
行 66: {
行 67: sb.AppendFormat("{0}: {1}\n", cookie.Name, cookie.Value);
.NET抱怨我霸王硬上弓把string轉型成HttpCookie,硬把繩子當餅乾。
這麼說來,foreach HttpRequestBase.Cookies會取得string而不是HttpCookie?
查了HttpCookieCollection的說明,文件範例寫for (int i = 0; i < cookies.Count; i++),不是用foreach,再追到HttpCookieCollection所繼承的父類別NameObjectCollectionBase,GetEnumerator()方法提到「這個列舉值會將集合的索引鍵當做字串傳回。」
謎底揭曉:用foreach列舉HttpCookieCollection,得到的是索引鍵字串(也就是Cookie名稱)而非HttpCookie物件,所以程式應改為:
public ActionResult TestCookies()
{
var req = this.HttpContext.Request;
StringBuilder sb = new StringBuilder();
foreach (string cookieName in req.Cookies)
{
sb.AppendFormat("{0}: {1}\n", cookieName, req.Cookies[cookieName]);
}
return Content(sb.ToString());
}
上了一課,BlahCollection跑foreach傳回的不一定是Blah型別,使用請先詳閱公開說明書。