一起谈.NET技术,ASP.NET4中不要相信Request.Browser.Cookies,Form验证要用UseCookies

  从ASP.NET 3.5升级至ASP.NET4之后,遇到三种登录后不能保存cookie的情况(升级前一切正常):

  1. 遨游3在极速模式下(默认模式)。

  2. FireFox中修改了UserAgent。

  3. 诺基亚手机自带浏览器或者UCWeb浏览器访问博客园手机版(m.cnblogs.com)。

  今天终于把罪魁祸首给揪出来了,它就是Request.Browser.Cookies。

  如果你在程序中使用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(可能还有更多误判的情况)。

  而在ASP.NET 3.5及ASP.NET 2.0不存在这样的误判。不信的话,大家用下面的代码验证一下:

  Response.Write(Request.Browser.Cookies);

  用遨游3在极速模式下访问,若是ASP.NET4,则显示False;若是ASP.NET 3.5,则显示True。

  本来准备写到这里就结束,但是在写的过程中,觉得不甘心,被这个折腾的差点崩溃,一定要看个究竟,ASP.NET4凭什么认为遨游3不支持cookie。

  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"就完事,不会有接下来的深入研究。

  当你有一个收获,通过博客写出来之后,不仅加深了这个收获,很多时候你还会有意外的收获...

时间: 2024-10-02 11:06:08

一起谈.NET技术,ASP.NET4中不要相信Request.Browser.Cookies,Form验证要用UseCookies的相关文章

ASP.NET4中不要相信Request.Browser.Cookies,“.NET研究”Form验证要用UseCookies

从ASP.NET 3.5升级至ASP.NET4之后,遇到三种登录后不能保存cookie的情况(升级前一切正常): 1. 遨游3在极速模式下(默认模式). 2. FireFox中修改了UserAgent上海徐汇企业网站设计与制作. 3. 诺基亚手机自带浏览器或者UCWeb浏览器访问博客园手机版(m.cnblogs.com). 今天终于把罪魁祸首给揪出来了,它就是Request.Browser.Cookies. 如果你在程序中使用Form验证并使用cookie保存用户的登录状态,请切记:在<auth

通过代码理解Asp.net4中的几种ClientIDMode设置.

以前我们可以通过ClientID在JavaScript脚本中服务器端控件.比如: document.getElementById("<%=控件.ClientID %>"); 这种方式不方便,而且如果在有数据绑定的控件中嵌套着子控件,则访问更不太方便了. 现在,在Asp.Net4中,对于控件增加了一种新的属性,名为ClientIDMode.通过设置ClientIDMode,我们可以指定各个服务器控件如何生成ClientID,以便我们在客户端脚本中方便使用.具体如下: 1.  

asp.net中使用基于角色的身份Forms验证,大致分为四个步骤

asp.net asp.net中使用基于角色的身份Forms验证,大致分为四个步骤1.配置系统文件web.config<system.web> <authentication mode="Forms" >  <forms name=".yaoCookies" loginUrl="/duan/Manage/login.aspx" protection="All"  timeout="20&

如何在asp.net中对表单进行有选择的验证

问题描述 如何在asp.net中对表单进行有选择的验证,最好是VBscrip的,哪位能给指点一下,谢谢! 解决方案 解决方案二:无语解决方案三:我的意思是我在同一个页面上有2个提交按钮,每个提交按钮都分别要对不同的控件进行验证,怎样才能实现呢?

一起谈.NET技术,Silverlight中本地化的实现

对于本地化这个功能我个人一直觉得在需求阶段就要确定该项目需不需要实行本地化,这样后面就可以减轻许多工作量,Sl中对本地化功能的支持与ASP.NET中一样,主要使用CultureInfo类来完成的. 下面来看实现本地化的具体流程,先来看一看我的项目结构:  这里我是把资源文件放入单独的项目中,这样结构上也比较的清晰. 第一步:先在Languages项目下添加几个资源文件,这里对于资源的命名要遵循.NET命名规范,比如说当前文化是中文的话,系统就会自动到Localization.zh-CN.resx

ASP.NET中对表单输入行有选择验证

asp.net 在ASP.NET中,有一系列的验证控件,可以很方便地验证用户输入的数据是否合法.尽管这些验证控件十分强大并且容易使用,但它们有一个缺点,那就是,一般在使用它们的时候,在提交网页时,都要对整个网页的用户输入进行验证.在验证控件中,没有一种直接的方法,可以只验证页面中某些部分的输入.本文将介绍如何利用asp.net验证控件以及javascript特性,完成只验证页面中某些部分的输入的功能. 为什么有的时候,只需要对页面的某些部分的输入进行验证呢?举一个例子,在某些应用中,有的时候为了

一起谈.NET技术,Silverlight实例教程 - Out of Browser与Office的互操作

Silverlight 实例教程索引 Silverlight 实例教程 - Out of Browser开篇 Silverlight 实例教程 - Out of Browser配置,安装和卸载 Silverlight 实例教程 - Out of Browser的自定义应用 Silverlight 实例教程 - Out of Browser存取本地文件系统 Silverlight 实例教程 - Out of Browser与COM的交互基础 Silverlight 实例教程 - Out of Br

一起谈.NET技术,.Net4.0 Parallel编程(二)Data Parallelism 中

在上篇文章中看过了使用Parrallel.For.Parael.Foreach在效率上给我们带来的提高.本文就来如何终止循环.线程局部变量 进行说明. Thread-Local Variables 首先我们来看下线程局部变量,是的我们也许一直在想我们如何去定义一个线程局部变量呢.先看段顺序执行的代码: [TestMethod()]public void NormalSequenceTest(){int[] nums = Enumerable.Range(0, 1000000).ToArray()

动态网页制作技术ASP开发中的常见问题

动态|网页|问题 <table style="TABLE-LAYOUT: fixed" width="200" border="0" cellspacing="0" cellpadding="7" bgcolor="#f7f7f7"> <tr> <td style="LEFT: 0px; WIDTH: 100%; WORD-WRAP: break-