從ASP.NET 3.5升級至ASP.NET4以後,遇到三種登陸後不能保存cookie的狀況(升級前一切正常):瀏覽器
1. 遨遊3在極速模式下(默認模式)。cookie
2. FireFox中修改了UserAgent。less
3. 諾基亞手機自帶瀏覽器或者UCWeb瀏覽器訪問博客園手機版(m.cnblogs.com)。測試
今天終於把罪魁禍首給揪出來了,它就是Request.Browser.Cookies。3d
若是你在程序中使用Form驗證並使用cookie保存用戶的登陸狀態,請切記:在<authentication mode="Forms">/<forms>中要加上cookieless="UseCookies"。若是不這樣設置的話,cookieless會使用默認值UseDeviceProfile。用了UseDeviceProfile,悲劇就發生了,ASP.NET會根據Request.Browser.Cookies來判斷當前瀏覽器是否支持Cookie(如若不信,請用Reflector查看System.Web.Security.FormsAuthentication的代碼)。而Request.Browser.Cookies會認爲上面的三種狀況不支持cookie(可能還有更多誤判的狀況)。orm
而在ASP.NET 3.5及ASP.NET 2.0不存在這樣的誤判。不信的話,你們用下面的代碼驗證一下:blog
Response.Write(Request.Browser.Cookies);get
用遨遊3在極速模式下訪問,如果ASP.NET4,則顯示False;如果ASP.NET 3.5,則顯示True。博客
原本準備寫到這裏就結束,可是在寫的過程當中,以爲不甘心,被這個折騰的差點崩潰,必定要看個究竟,ASP.NET4憑什麼認爲遨遊3不支持cookie。it
1)先用下面的代碼看一下ASP.NET4把遨遊3當成什麼瀏覽器:
Response.Write(Request.Browser.Browser);
答案是:Safari
難道微軟在這裏搞了小花招,只要是Safari,故意認爲它不支持cookie。
用正宗的Safari測試了一下,Request.Browser.Cookies返回True。冤枉微軟了,微軟也不會這麼小家子氣。
2) 再用Request.UserAgent看一下遨遊3的UserAgent:
結果是:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/533.9 (KHTML, like Gecko) Maxthon/3.0 Safari/533.9
雙核瀏覽器是果真不一樣反響。難道是複雜的UserAgent讓ASP.NET4很惱火:誰家的瀏覽器這麼複雜,乾脆斷定你不支持cookie。
3) 接下來是關鍵的一步,找出ASP.NET4根據什麼判斷當前瀏覽器是否支持cookie?能夠肯定的是,不是拋硬幣拋出來的。
用Reflector看源代碼,看得頭昏腦脹,也沒找到答案。算了,那就用殺手鐗——猜想法。嘿嘿,這招居然管用。
原來ASP.NET4是根據下面的文件夾中的數據進行判斷的:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\Browsers
打開這個文件夾一看:
眼前一亮,火燒眉毛地打開safari.browser:
呵呵,原來真相躲在這裏。稍微分析一下這個文件,就能知道:
遨遊3匹配的是第一項(也就是<browser id="Safari" parentID="Mozilla">部分),這項配置中沒有設置cookies=true。
而正宗的Safari不只匹配了第一項,還匹配了第二項,(也就是<browser id="Safari3to4" parentID="Safari">部分)這裏設置了<capability name="cookies" value="true" />。
果真是遨遊3「冒充」別人家的瀏覽器形成的,微軟沒想到會出現這樣的的UserAgent。
找到真相,問題就容易解決了。開始覺得只要在第一項中加<capability name="cookies" value="true" />就好了,但沒這麼簡單:
1. safari.browser文件修改不能保存,提示說是隻讀文件。解決方法是:將safari.browser複製到其餘地方,改好後,再複製回來,覆蓋現有文件。
2. 要以管理員身份運行下面的命令將這些.browser文件編譯成程序集並安裝到GAC中:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regbrowsers.exe –i
搞定!終於真相大白,不枉一場折騰。
若是不寫這篇隨筆,可能加上cookieless="UseCookies"就完事,不會有接下來的深刻研究。
當你有一個收穫,經過博客寫出來以後,不只加深了這個收穫,不少時候你還會有意外的收穫...