[MSDN]通过避免下列 10 个常见 ASP.NET 缺陷使网站平

作者:足球

透过制止下列 10 个常见 ASP.NET 缺欠使网址平稳运营

发表日期: 二〇〇七-07-11 | 更新日期: 二零零七-07-11

Jeff Prosise

正文将切磋:

缓存和 Forms 身份验证

视图状态和会话状态

配置文件属性序列化

线程池饱和

模拟和设置配置文件

正文使用了下列本领:

.NET Framework、ASP.NET、Windows Server 2003

www0907com 1

原文:

本页内容
LoadControl 和输出缓存
会话和输出缓存
Forms 身份验证票证生存期
视图状态:无声的性能杀手
SQL Server 会话状态:另一个性能杀手
未缓存的角色
配置文件属性序列化
线程池饱和
模拟和 ACL 授权
不要完全信赖它 — 请设置数据库的配置文件!
结论

ASP.NET 成功的内部叁个缘由在于它减弱了 Web 开垦人士的门槛。固然你不是计算机科学大学子也得以编写制定 ASP.NET 代码。我在专门的学业中碰着的居多 ASP.NET 开辟职员都以自学成材的,他们在编排 C# 或 Visual Basic® 早前都在编排 Microsoft® Excel® 石英手表格。今后,他们在编辑 Web 应用程序,总的来讲,他们所做的办事值得赞叹。

但是与力量随之而来的还应该有权利,固然是经验丰盛的 ASP.NET 开垦人士也难免会出错。在多年的 ASP.NET 项目咨询办事中,笔者意识一些错误极度轻易导致缺欠不断发生。此中一些错误会耳熟能详属性。其余错误会防止可伸缩性。有个别错误还有只怕会使开采组织花费宝贵的时刻来追踪错误和奇异的一颦一笑。

下边是会招致 ASP.NET 生产应用程序的透露进程中出现难题的 11个毛病以致可幸免它们的方法。全部示例均来源于自个儿对量体裁衣的商家创设真正的 Web 应用程序的亲自体验,在一些境况下,作者会通过介绍 ASP.NET 开采团队在开垦进程中碰到的一些难点来提供相关的背景。

ASP.NET 成功的中间贰个原因在于它裁减了 Web 开拓人士的法门。纵然你不是计算机科研生也足以编写 ASP.NET 代码。小编在专业中境遇的成都百货上千 ASP.NET 开垦职员都以自学成材的,他们在编制C# 或 Visual Basic® 在此之前都在编写制定 Microsoft® Excel® 石英钟格。将来,他们在编排 Web 应用程序,总的来讲,他们所做的劳作值得陈赞。

LoadControl 和输出缓存

极罕见不使用顾客控件的 ASP.NET 应用程序。在产出母版页早先,开垦人士使用顾客控件来提取公用内容,如页眉和页脚。就算在 ASP.NET 2.0 中,顾客控件也提供了卓有成效的方式来封装内容和行为以致将页面分为多少个区域,那些区域的缓存技巧能够独立于作为完整的页面实行支配(人山人海种名为段缓存的非常输出缓存方式)。

客户控件能够行使注解的格局加载,也足以强制加载。强制加载正视于 Page.LoadControl,它实例化客商控件并重回控件援用。倘使顾客控件包括自定义类型的分子(例如,公共属性),则您可以转移该援引并从你的代码访问自定义成员。图 1 中的客商控件完成名称叫 BackColor 的性质。以下代码加载客商控件并向 BackColor 分配二个值:

protected void Page_Load(object sender, EventArgs e)
{
// 加载用户控件并将其添加到页面中
Control control = LoadControl("~/MyUserControl.ascx");
PlaceHolder1.Controls.Add(control);
// 设置其背景色
((MyUserControl)control).BackColor = Color.Yellow;
}

以上代码实际上很简单,但却是四个等候马虎的开采职员掉进去的圈套。您能寻找里面的破损吗?

借让你猜到该难点与输出缓存有关,那么您是科学的。正如您所观望的相像,上述代码示例编写翻译和平运动行都健康,然而只要尝试将以下语句(完全合法)增加到 MyUserControl.ascx 中:

<%@ OutputCache Duration="5" VaryByParam="None" %>

则当你下二次运维该页面时,您将看见 InvalidCastException (oh joy!) 和以下错误音信:

“无法将类型为‘System.Web.UI.PartialCachingControl’的对象转换为类型‘MyUserControl’。”

因而,此代码在未曾 OutputCache 指令时运维符合规律化,但只要增多了 OutputCache 指令就能出错。ASP.NET 不应当以这种情势运转。页面(和控件)对于出口缓存应该是不可以预知的。那么,那意味如何意思?

主题材料在于为客户控件启用输出缓存时,LoadControl 不再归来对控件实例的援引;相反,它回到对 PartialCachingControl 实例的援引,而 PartialCachingControl 可能会也或者不会卷入控件实例,具体决定于控件的输出是还是不是被缓存。由此,假使开拓职员调用 LoadControl 以动态加载客户控件况兼为了访问控件特定的措施和总体性而调换控件援用,他们不得不小心进行该操作的不二法门,以便不管是否持有 OutputCache 指令,代码都可以运作。

图 2 表达动态加载客商控件以至转变重返的控件引用的不易方法。以下是其事业规律概要:

如果 ASCX 文件缺少 OutputCache 指令,则 LoadControl 返回一个 MyUserControl 引用。Page_Load 将该引用转换为 MyUserControl 并设置控件的 BackColor 属性。

如果 ASCX 文件包括一个 OutputCache 指令并且控件的输出没有被缓存,则 LoadControl 返回一个对 PartialCachingControl 的引用,此 PartialCachingControl 的 CachedControl 属性包含对基础 MyUserControl 的引用。Page_Load 将 PartialCachingControl.CachedControl 转换为 MyUserControl 并设置该控件的 BackColor 属性。

如果 ASCX 文件包括一个 OutputCache 指令并且控件的输出被缓存,则 LoadControl 返回一个对 PartialCachingControl(其 CachedControl 属性为空)的引用。注意,Page_Load 不再继续执行操作。无法设置控件的 BackColor 属性,因为该控件的输出来源于输出缓存。换句话说,根本没有要设置属性的 MyUserControl。

无论 .ascx 文件中是还是不是具有 OutputCache 指令,图 2中的代码都将运营。尽管看起来复杂一点,但它会防止烦人的大错特错。简单并不三回九转代表轻便维护。

www0907com 2回到页首

而是与力量随之而来的还大概有权利,纵然是经验足够的 ASP.NET 开采人士也难免会出错。在连年的 ASP.NET 项目咨询办事中,作者发掘一些错误非常容易形成缺欠不断发出。个中一些错误会影响属性。别的错误会幸免可伸缩性。有个别错误还有大概会使开拓团队开销宝贵的年华来追踪错误和意想不到的行事。

对话和输出缓存

谈到输出缓存,ASP.NET 1.1 和 ASP.NET 2.0 都存在一个诡秘的标题,该难点会耳濡目染在 Windows Server™ 二〇〇〇 和 IIS 6.0 上运转的服务器中的输出缓存页。作者早已亲眼看到该难点在 ASP.NET 生产服务器中出现过四回,这两遍都是通过关闭输出缓冲来缓和的。后来作者打听到有一个比禁止使用输出缓存更加好的应用方案。以下是自个儿第二回碰到该难题时的动静。

旋即的事态是那样的,某些网址(大家在这里称呼 Contoso.com,它在Mini ASP.NET Web 领域中运营公共电子商务应用程序)与自家的团体交流,抱怨他们遇到了“跨线程”错误。使用 Contoso.com 网站的客商平常忽然不见已经输入的数码,但却看见另风华正茂客商的有关数据。稍做深入分析即开掘,跨线程这几个描述并不规范;“跨会话”错误更加的方便。看起来 Contoso.com 是在对话状态中贮存数据的,由于某个原因,客商会不常随机地一而再到别的顾客的对话。

自笔者的三个团伙成员编写了一个确诊工具,用来将各类 HTTP 央浼和响应的主要性要素(包括 Cookie 标头)记录到日志中。然后,他将该工具安装在 Contoso.com 的 Web 服务器上,并让其运作了几天。结果丰硕显然。大致每 100000 个诉求中会发生二回那样的情事:ASP.NET 正确地为全新会话分配三个会话 ID 并回到 Set-Cookie 标头中的会话 ID。然后,它会在下多少个紧相邻的需要中回到相近的对话 ID(即,相像的 Set-Cookie 标头),固然该央浼已经与一个立见效能的对话相关联並且正确提交了 Cookie 中的会话 ID。实际上,ASP.NET 是即兴将客商从她们本人的对话中切换出去并将他们再三再四到任何会话。

大家很愕然,于是从头物色原因。我们率先检查了 Contoso.com 的源代码,让大家倍感欣尉的是,难题不在那。接着,为了保障难题与应用程序宿主在 Web 领域毫无干系,大家只保留一个服务器在运营,而关闭了具有其余服务器。难点照旧存在,那并不意外,因为大家的日记显示相称的 Set-Cookie 标头绝不会来自四个不相同的服务器。ASP.NET 意各省生成了再一次的对话 ID,这令人不敢相信 无法相信,因为它采纳 .NET Framework 讴歌RDXNGCryptoServiceProvider 类生成那一个 ID,况兼会话 ID 的长度能够保证同等的 ID 决不会扭转四次(最少在下二个万亿年内不会转移三回)。除此而外,就算EvoqueNGCryptoServiceProvider 错误地生成了再也的私下数字,也无法解释 ASP.NET 为啥出乎意料地将有效的对话 ID 替换为新的 ID(不唯大器晚成)。

凭直觉,我们决定看一下输出缓存。当 OutputCacheModule 缓存 HTTP 响合时,它必妥帖心不要缓存了 Set-Cookie 标头;不然,富含新会话 ID 的缓存响应会将缓存响应的兼具接受者(以致其诉求生成了缓存响应的客商)连接到同一会话。我们检查了源代码;Contoso.com 在三个页面中启用了出口缓存。我们关闭了出口缓存。结果,应用程序运维好多天而并未有生出叁个跨会话难题。从此,它运行了八年多都未曾发生任何不当。在具备分化应用程序和意气风发组差异Web 服务器的另一家集团中,大家来看完全相符的标题也消失殆尽了。就好像在 Contoso.com 同样,消弭输出缓存就能够一蹴而就难点。

Microsoft 后来确认此行为来自 OutputCacheModule 中的难点。(当你读书本文时,大概早就发布了履新。)当 ASP.NET 与 IIS 6.0 一齐行使而且启用内核方式缓存时,OutputCacheModule 一时不恐怕从它传递给 Http.sys 的缓存响应中除去 Set-Cookie 标头。下边是促成出现谬误的一定事件顺序:

最近没有访问网站(因此也没有对应的会话)的用户请求一个启用了输出缓存的页面,但是其输出当前在缓存中不可用。

该请求执行用于访问用户最新创建的会话的代码,从而导致会话 ID Cookie 在响应的 Set-Cookie 标头中返回。

OutputCacheModule 向 Http.sys 提供输出,但是无法从响应中删除 Set-Cookie 标头。

Http.sys 在后续的请求中返回缓存响应,误将其他用户连接到会话。

好玩的事的味道又是何等啊?会话状态和水源格局输出缓存不可能混合使用。假如你在启用输出缓存的页中使用会话状态,而且应用程序在 IIS 6.0 上运营,则您必要关闭内核方式输出缓存。您仍将收益于出口缓存,可是因为基础格局输出缓存比日常输出缓存快得多,所以缓存不会相符有效。有关此主题素材的详细音信,请参见 support.microsoft.com/kb/917072。

你能够透过在页面包车型客车 OutputCache 指令中包含 VaryByParam="*" 属性来关闭单个页面包车型大巴基业情势输出缓存,纵然那样做恐怕导致内部存储器供给急剧增加。另风姿洒脱种更安全的措施是透过在 web.config 中包含下列成分来关闭全数应用程序的内核形式缓存:

<httpRuntime enableKernelOutputCache="false" />

您还足以采取注册表设置来全局性地剥夺内核形式输出缓存,即禁止使用全数服务器的木本格局输出缓存。有关详细音讯,请参见 support.microsoft.com/kb/820129。

老是自身听到客商报告会话产生了费解的标题,作者都会询问他们是还是不是在其余页面中央银行使了出口缓存。假使确实使用了出口缓存,并且宿主操作系统是 Windows Server 二〇〇三,笔者会提议她们禁止使用内核格局输出缓存。难点普通就能够缓和。假如难题还未消除,则错误存在于代码中。警惕!

www0907com 3回去页首

上边是会招致 ASP.NET 生产应用程序的公布进度中出现难题的 11个破绽以致可制止它们的主意。全数示例均出自己对实际的厂商创设真正的 Web 应用程序的切身体验,在一些情形下,作者会通过介绍 ASP.NET 开拓团队在付出进程中遇见的一些难题来提供有关的背景。

Forms 身份验证票证生存期

您能搜索以下代码的难题吧?

FormsAuthentication.RedirectFromLoginPage(username, true);

此代码看似没格外,但一定不可能在 ASP.NET 1.x 应用程序中利用,除非应用程序中任何职责的代码抵消了此语句的阴暗面作用。纵然你不能鲜明原因,请继续读书。

FormsAuthentication.RedirectFromLoginPage 试行三个义务。首先,当 FormsAuthenticationModule 将客商重定向到登入页时,FormsAuthentication.RedirectFromLoginPage 将客商重定向到他俩原本哀告的页面。其次,它揭露二个身份验证票证(经常教导在 库克ie 中,何况在 ASP.NET 1.x 中三番三次带领在 库克ie 中),这几个单子允许顾客在预定的风流倜傥段时间内保障已通过身份验证状态。

标题就在于那些小时段。在 ASP.NET 1.x 中,向 RedirectFromLoginPage 传递另二个为 false 的参数会生出叁个近日身份验证票证,该票证暗许景况下在 30 分钟之后到期。(您能够接收 web.config 的 成分中的 Timeout 属性来改革超时代限。)然则,传递另一个为 true 的参数则会发出一个永恒身份验证票证,其保质期为 50 年!这样就能够发生难题,因为只要有人偷取了该身份验证票证,他们就足以在单据的保藏期内使用受害者的地位会见网站。偷取身份验证票证有三种办法 — 在公私无线访谈点探测未加密的通信、跨网址编写脚本、以物理格局访谈受害者的Computer等等 — 由此,向 RedirectFromLoginPage 传递 true 比禁止使用你的网址的安全性好持续多少。幸运的是,此主题材料早已在 ASP.NET 2.0 中收获了消除。今后的 RedirectFromLoginPage 以相像的不二等秘书籍选取在 web.config 中为一时和永久身份验证票证内定的逾期。

黄金时代种缓和方案是绝不在 ASP.NET 1.x 应用程序的 RedirectFromLoginPage 的第三个参数中传送 true。可是那不符合实际,因为登陆页的表征常常是蕴含二个“将笔者保持为记名状态”框,客户能够选中该框以吸取永恒并非临时身份验证 Cookie。另大器晚成种减轻方案是应用 Global.asax(借让你愿意的话,也能够使用 HTTP 模块)中的代码段,此代码段会在蕴藏永远身份验证票证的 Cookie 再次回到浏览器以前对其开展更改。

图 3 包蕴贰个这么的代码段。假诺此代码段位于 Global.asax 中,它会改正传出长久Forms 身份验证 Cookie 的 Expires 属性,以使 Cookie 在 24 时辰后过期。通过退换注释为“新的逾期日期”的行,您能够将过期设置为你喜爱的别样日期。

你或然会认为诡异,Application_EndRequest 方法调用本地 Helper 方法 (GetCookieFromResponse) 来检查身份验证 库克ie 的传入响应。Helper 方法是焚林而猎 ASP.NET 1.1 中另三个不当的艺术,要是你使用 HttpCookieCollection 的字符串索引生成器来检查不设有的 Cookie,此错误会形成虚假 Cookie 加多到响应中。使用整数索引生成器作为 GetCookieFromResponse 能够减轻该难点。

www0907com 4再次来到页首

LoadControl 和出口缓存

极罕见不行使客商控件的 ASP.NET 应用程序。在产出母版页在此之前,开拓职员使用顾客控件来领取公用内容,如页眉和页脚。即便在 ASP.NET 2.0 中,顾客控件也提供了卓有成效的点子来封装内容和行为以致将页面分为八个区域,那几个区域的缓存技术能够独自于作为完全的页面实行支配(意气风发种名称叫段缓存的特别输出缓存情势)。

客户控件能够动用证明的点子加载,也能够强制加载。强制加载信任于 Page.LoadControl,它实例化客户控件并回到控件引用。借使客商控件蕴涵自定义类型的成员(比如,公共属性),则您可以转变该援用并从你的代码访谈自定义成员。www0907com,图 1 中的客户控件达成名称叫 BackColor 的性质。以下代码加载客商控件并向 BackColor 分配二个值:

protected void Page_Load(object sender, EventArgs e)
{
// 加载用户控件并将其添加到页面中
Control control = LoadControl("~/MyUserControl.ascx");
PlaceHolder1.Controls.Add(control);
// 设置其背景色
((MyUserControl)control).BackColor = Color.Yellow;
}

如上代码实际上相当的粗略,但却是三个等候大意的开垦人士掉进去的牢笼。您能找寻里面包车型大巴破损吗?

若是你猜到该难题与出口缓存有关,那么您是没有什么可争辨的的。正如你所见到的蒸蒸日上律,上述代码示例编写翻译和平运动行都例行,可是只要尝试将以下语句(完全合法)加多到 MyUserControl.ascx 中:

<%@ OutputCache Duration="5" VaryByParam="None" %>

则当你下三次运行该页面时,您将见到 InvalidCastException (oh joy!) 和以下错误音信:

“无法将类型为‘System.Web.UI.PartialCachingControl’的对象转换为类型‘MyUserControl’。”

据此,此代码在还未有 OutputCache 指令时运行如常,但假设增加了 OutputCache 指令就可以出错。ASP.NET 不应有以这种方法运营。页面(和控件)对于出口缓存应该是不可以看到的。那么,这表示怎样意思?

难点在于为客户控件启用输出缓存时,LoadControl 不再回来对控件实例的援引;相反,它回到对 PartialCachingControl 实例的引用,而 PartialCachingControl 恐怕会也说不定不会卷入控件实例,具体决议于控件的出口是或不是被缓存。因而,要是开垦人士调用 LoadControl 以动态加载客商控件并且为了访问控件特定的法子和性质而更改控件援引,他们必得小心举办该操作的点子,以便不管是还是不是具有OutputCache 指令,代码都足以运维。

图 2 表明动态加载客商控件以至调换再次来到的控件援引的没错方法。以下是其行事原理概要:

如果 ASCX 文件缺少 OutputCache 指令,则 LoadControl 返回一个 MyUserControl 引用。Page_Load 将该引用转换为 MyUserControl 并设置控件的 BackColor 属性。

如果 ASCX 文件包括一个 OutputCache 指令并且控件的输出没有被缓存,则 LoadControl 返回一个对 PartialCachingControl 的引用,此 PartialCachingControl 的 CachedControl 属性包含对基础 MyUserControl 的引用。Page_Load 将 PartialCachingControl.CachedControl 转换为 MyUserControl 并设置该控件的 BackColor 属性。

如果 ASCX 文件包括一个 OutputCache 指令并且控件的输出被缓存,则 LoadControl 返回一个对 PartialCachingControl(其 CachedControl 属性为空)的引用。注意,Page_Load 不再继续执行操作。无法设置控件的 BackColor 属性,因为该控件的输出来源于输出缓存。换句话说,根本没有要设置属性的 MyUserControl。

任由 .ascx 文件中是或不是富有 OutputCache 指令,图 2中的代码都将运行。即使看起来复杂一点,但它会制止烦人的失实。轻易并不总是代表轻巧维护。

www0907com 5重回页首

视图状态:无声的个性杀手

从某种意义上说,视图状态是有史以来最宏伟的事情。终归,视图状态使得页面和控件能够在回发之间保持状态。因而,您不要像在守旧的 ASP 中那样编写代码,以免止在单击按键时文本框中的文本消失,或在回发后再一次查询数据库和再一次绑定 DataGrid。

不过视图状态也是有重疾:当它增进得过大时,它便成为五个无声的习性徘徊花。某个控件(举例文本框)会根据视图状态作出相应决断。别的控件(极度是 DataGrid 和 GridView)则基于显示的音信量分明视图状态。假如 GridView 显示200 或 300 行数据,笔者会艰难险阻。尽管 ASP.NET 2.0 视图状态大概是 ASP.NET 1 x 视图状态的五成高低,二个糟糕的 GridView 也可以轻便地将浏览器和 Web 服务器之间的连年的管用带宽减弱 50% 或越来越多。

你能够透过将 EnableViewState 设置为 false 来关闭单个控件的视图状态,但某个控件(非常是 DataGrid)在不可能利用视图状态时会失去有些职能。调节视图状态的更佳建设方案是将其保存在服务器上。在 ASP.NET 1.x 中,您能够重写页面包车型地铁 LoadPageStateFromPersistenceMedium 和 SavePageStateToPersistenceMedium 方法并按你喜欢的方法管理视图状态。图 4 中的代码显示的重写可幸免视图状态保留在遮盖字段中,而将其保存在对话状态中。当与暗中同意会话状态进度模型一齐行使时(即,会话状态存款和储蓄在内部存款和储蓄器中的 ASP.NET 支持进度中时),在对话状态中储存视图状态更是有效。相反,借使会话状态存款和储蓄在数据库中,则独有测量检验本事呈现在对话状态中保留视图状态会加强或然下落品质。

在 ASP.NET 2.0 中利用同风姿洒脱的方法,不过 ASP.NET 2.0 能够提供更简便的法子将视图状态保留在对话状态中。首先,定义贰个自定义页适配器,其 GetStatePersister 方法重回 .NET Framework SessionPageStatePersister 类的三个实例:

public class SessionPageStateAdapter :
System.Web.UI.Adapters.PageAdapter
{
public override PageStatePersister GetStatePersister ()
{
return new SessionPageStatePersister(this.Page);
}
}

下一场,通过将 App.browsers 文件按以下措施放入应用程序的 App_Browsers 文件夹,将自定义页适配器注册为私下认可页适配器:

<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.Page"
adapterType="SessionPageStateAdapter" />
</controlAdapters>
</browser>
</browsers>

(您能够将文件命名称叫您喜欢的别的名称,只要它的扩大名字为 .browsers 就能够。)从此,ASP.NET 将加载页适配器并选择重回的 SessionPageStatePersister 以保存全部页面状态,包罗视图状态。

应用自定义页适配器的叁个欠缺是它全局性地功效于应用程序中的每风流倜傥页。假若您更乐于将内部有个别页面的视图状态保留在对话状态中而不保留其他页面的视图状态,请使用图 4 中展现的不二秘籍。别的,倘若客户在同一会话中开创几个浏览器窗口,您使用该措施可能会超过难点。

www0907com 6归来页首

对话和出口缓存

聊到输出缓存,ASP.NET 1.1 和 ASP.NET 2.0 都留存八个私人民居房的标题,该难题会潜濡默化在 Windows Server™ 二〇〇一 和 IIS 6.0 上运营的服务器中的输出缓存页。小编早就亲眼看见该难点在 ASP.NET 生产服务器中冒出过五回,那三回都以透过关闭输出缓冲来缓慢解决的。后来本身打听到有一个比禁用输出缓存越来越好的施工方案。以下是自己第贰回境遇该难题时的场地。

霎时的事态是如此的,有些网址(大家在那称呼 Contoso.com,它在小型 ASP.NET Web 领域中运营公共电子商务应用程序)与本人的团体沟通,抱怨他们碰到了“跨线程”错误。使用 Contoso.com 网址的顾客常常乍然错失已经输入的数码,但却见到另龙腾虎跃客商的有关数据。稍做剖析即开掘,跨线程这一个描述并不标准;“跨会话”错误越来越方便。看起来 Contoso.com 是在对话状态中蕴藏数据的,由于某个原因,客户会不时随机地连接到其余用户的对话。

自己的一个集团成员编写了二个会诊工具,用来将每一个 HTTP 诉求和响应的入眼因素(包罗 Cookie 标头)记录到日志中。然后,他将该工具安装在 Contoso.com 的 Web 服务器上,并让其运转了几天。结果十三分显著。差相当少每 100000 个须要中会发生三回那样的事态:ASP.NET 精确地为全新会话分配一个对话 ID 并赶回 Set-Cookie 标头中的会话 ID。然后,它会在下二个紧相邻的哀告中回到相近的对话 ID(即,近似的 Set-Cookie 标头),固然该乞求已经与四个低价的对话相关联而且精确提交了 Cookie 中的会话 ID。实际上,ASP.NET 是自由将客户从他们和煦的对话中切换出去并将她们连年到另外会话。

小编们很诡异,于是从头索求原因。大家先是检查了 Contoso.com 的源代码,让我们倍感欣尉的是,难点不在那。接着,为了确认保障难题与应用程序宿主在 Web 领域非亲非故,大家只保留多个服务器在运行,而关门大吉了具备其余服务器。难点仍旧存在,那并不意外,因为咱们的日记显示相称的 Set-Cookie 标头绝不会来自两个不等的服务器。ASP.NET 意外市生成了再也的对话 ID,那令人猜疑,因为它接受 .NET Framework CR-VNGCryptoServiceProvider 类生成这一个 ID,而且会话 ID 的尺寸可以有限支撑同等的 ID 决不会变卦四次(起码在下一个万亿年内不会扭转五遍)。除外,即便OdysseyNGCrypto瑟维斯Provider 错误地生成了双重的任意数字,也无法解释 ASP.NET 为啥难以置信地将实用的对话 ID 替换为新的 ID(不唯如火如荼)。

凭直觉,大家决定看一下输出缓存。当 OutputCacheModule 缓存 HTTP 响合时,它必得小心不要缓存了 Set-Cookie 标头;不然,包涵新会话 ID 的缓存响应会将缓存响应的兼具接收者(以至其央浼生成了缓存响应的顾客)连接到同一会话。大家检查了源代码;Contoso.com 在三个页面中启用了出口缓存。大家关闭了出口缓存。结果,应用程序运转数天而从不生出三个跨会话难点。从此以后,它运维了七年多都不曾产生别的错误。在具备分裂应用程序和后生可畏组不一致Web 服务器的另一家商店中,大家见到完全相像的主题素材也瓦解冰消了。就像是在 Contoso.com 相似,消释输出缓存就会消除难点。

Microsoft 后来确认此行为来自 OutputCacheModule 中的难题。(当你读书本文时,可能早已昭示了履新。)当 ASP.NET 与 IIS 6.0 一齐利用而且启用内核情势缓存时,OutputCacheModule 不常不能从它传递给 Http.sys 的缓存响应中删去 Set-Cookie 标头。上面是导致出现错误的特定事件顺序:

最近没有访问网站(因此也没有对应的会话)的用户请求一个启用了输出缓存的页面,但是其输出当前在缓存中不可用。

该请求执行用于访问用户最新创建的会话的代码,从而导致会话 ID Cookie 在响应的 Set-Cookie 标头中返回。

OutputCacheModule 向 Http.sys 提供输出,但是无法从响应中删除 Set-Cookie 标头。

Http.sys 在后续的请求中返回缓存响应,误将其他用户连接到会话。

故事的味道又是怎么着吧?会话状态和水源形式输出缓存不能够混合使用。要是你在启用输出缓存的页中使用会话状态,何况应用程序在 IIS 6.0 上运维,则您供给关闭内核方式输出缓存。您仍将收益于出口缓存,可是因为基础形式输出缓存比平时输出缓存快得多,所以缓存不会近似有效。有关此难题的详细音讯,请参见 support.microsoft.com/kb/917072。

你能够透过在页面包车型客车 OutputCache 指令中蕴藏 VaryByParam="*" 属性来关闭单个页面包车型客车内核格局输出缓存,就算那样做只怕导致内部存款和储蓄器必要剧增。另热气腾腾种更安全的主意是透过在 web.config 中含有下列成分来关闭全数应用程序的基业形式缓存:

<httpRuntime enableKernelOutputCache="false" />

您还足以接受注册表设置来全局性地剥夺内核格局输出缓存,即禁止使用全部服务器的基本形式输出缓存。有关详细消息,请参见 support.microsoft.com/kb/820129。

每一次自个儿听到顾客报告会话发生了费解的标题,小编都会询问她们是或不是在别的页面中利用了出口缓存。固然的确使用了出口缓存,而且宿主操作系统是 Windows Server 二〇〇二,作者会建议他们禁止使用内核方式输出缓存。难题普通就能化解。假如难题并未有缓慢解决,则错误存在于代码中。警惕!

www0907com 7归来页首

SQL Server 会话状态:另六特性能杀手

ASP.NET 使得在数据库中存放会话状态变得轻松:只需切换 web.config 中的按键,会话状态就能轻易地活动到后端数据库。对于在 Web 领域中运转的应用程序来讲,那是意气风发项首要效能,因为它同意该领域中的每一个服务器分享会话状态的三个公共库。加多的数据库活动降低了单个诉求的性质,可是可伸缩性的拉长弥补了质量的损失。

那看起来都还不易,不过你略微思量一下下列几点,意况就能够迥然不相同:

即使在使用会话状态的应用程序中,大多数页也不使用会话状态。

默认情况下,ASP.NET 会话状态管理器对每个请求中的会话数据存储执行两个访问(一个读取访问和一个写入访问),而不管请求的页是否使用会话状态。

换句话说,当你使用 SQL Server™ 会话状态选项时,您在每一种哀告中都要付出代价(五个数据库访问)— 甚至在与会话状态非亲非故的页面的伸手中。那会一贯对总体网址的吞吐量形成负面影响。

www0907com 8

图 5 清除不供给的对话状态数据库访问

那么你应该咋做吧?超轻巧:禁止使用不接收会话状态的页中的会话状态。那样做总是多少个好情势,可是当会话状态存款和储蓄在数据库中时,该措施尤其首要。图 5 展现怎么禁止使用会话状态。尽管页面根本不利用会话状态,请在其 Page 指令中富含 EnableSessionState="false",如下所示:

<%@ Page EnableSessionState="false" ... %>

该指令阻止会话状态管理器在每种诉求中读取和写入会话状态数据库。如若页面从会话状态中读取数据,但却不写入数据(即,不变顾客会话的原委),则将 EnableSessionState 设置为 ReadOnly,如下所示:

<%@ Page EnableSessionState="ReadOnly" ... %>

末段,倘诺页面要求对会话状态进行读/写访问,则省略 EnableSessionState 属性或将其设置为 true:

<%@ Page EnableSessionState="true" ... %>

因此以这种艺术调节会话状态,能够保险 ASP.NET 只在真正须要时才访谈会话状态数据库。消逝无需的数据库访问是创设高质量应用程序的首先步。

附带说一下,EnableSessionState 属性是青霄白日的。该属性自 ASP.NET 1.0 以来就曾经展开了注脚,不过本身迄今仍超少看见开采人士利用该属性。只怕是因为它对于内部存款和储蓄器中的默许会话状态模型并不要命珍视。但是它对于 SQL Server 模型却很要紧。

www0907com 9再次回到页首

Forms 身份验证票证生存期

您能寻找以下代码的主题材料吗?

FormsAuthentication.RedirectFromLoginPage(username, true);

此代码看似没不寻常,但不可能在 ASP.NET 1.x 应用程序中应用,除非应用程序中任何地点的代码抵消了此语句的负面成效。尽管您不可能明确原因,请继续阅读。

FormsAuthentication.RedirectFromLoginPage 实行多少个职务。首先,当 FormsAuthenticationModule 将客户重定向到登入页时,FormsAuthentication.RedirectFromLoginPage 将客商重定向到他们本来央求的页面。其次,它发表二个身份验证票证(经常教导在 库克ie 中,并且在 ASP.NET 1.x 中一连辅导在 Cookie 中),那个单子允许客商在约定的豆蔻梢头段时间内维持已因此身份验证状态。

难点就在于那些日子段。在 ASP.NET 1.x 中,向 RedirectFromLoginPage 传递另二个为 false 的参数会发出贰个有的时候身份验证票证,该票证暗中认可情形下在 30 分钟过后到期。(您能够利用 web.config 的 成分中的 Timeout 属性来更改超时代限。)可是,传递另叁个为 true 的参数则会发生三个永世身份验证票证,其保质期为 50 年!那样就能发生难题,因为倘诺有人偷取了该身份验证票证,他们就可以在单据的保藏期内采用受害者的身份拜谒网址。偷取身份验证票证有多样主意 — 在公共有线访谈点探测未加密的通讯、跨网站编写脚本、以物理方法访谈受害者的Computer等等 — 由此,向 RedirectFromLoginPage 传递 true 比禁止使用你的网址的安全性好持续多少。幸运的是,此主题素材已经在 ASP.NET 2.0 中获取了解决。今后的 RedirectFromLoginPage 以平等的措施接收在 web.config 中为一时和祖祖辈辈身份验证票证内定的超时。

黄金年代种缓和方案是绝不在 ASP.NET 1.x 应用程序的 RedirectFromLoginPage 的第3个参数中传送 true。可是那不合实际,因为登入页的特色日常是含有一个“将自己保持为记名状态”框,顾客能够选中该框以吸收永远并不是不时身份验证 库克ie。另风姿浪漫种缓和方案是选取 Global.asax(假如你愿意的话,也能够动用 HTTP 模块)中的代码段,此代码段会在含有长久身份验证票证的 Cookie 再次来到浏览器此前对其举行修正。

图 3 包涵一个这么的代码段。假使此代码段位于 Global.asax 中,它会修改传出永远Forms 身份验证 Cookie 的 Expires 属性,以使 Cookie 在 24 小时后过期。通过改进注释为“新的超时日期”的行,您能够将过期设置为你喜欢的别的日期。

你也许会以为意外,Application_EndRequest 方法调用本地 Helper 方法 (GetCookieFromResponse) 来检查身份验证 Cookie 的扩散响应。Helper 方法是消除 ASP.NET 1.1 中另三个不当的主意,假若您使用 HttpCookieCollection 的字符串索引生成器来检查子虚乌有的 Cookie,此错误会招致虚假 Cookie 增添到响应中。使用整数索引生成器作为 GetCookieFromResponse 能够消除该难点。

www0907com 10回来页首

未缓存的剧中人物

以下语句日常出现于 ASP.NET 2.0 应用程序的 web.config 文件以至介绍 ASP.NET 2.0 剧中人物管理器的身体力行中:

<roleManager enabled="true" />

但正如以上所示,该语句实在会对品质发生刚强的负面影响。您领悟怎么吗?

暗中同意情状下,ASP.NET 2.0 剧中人物管理器不会缓存角色数据。相反,它会在每趟必要规定顾客属于哪个剧中人物(假若有)时参照他事他说加以考察角色数据存款和储蓄。那表示要是客商通过了身份验证,任何利用角色数据的页(譬喻,使用启用了平安收缩设置的网站图的页,以至使用 web.config 中基于剧中人物的 URL 指令打开拜访受到限定的页)将促成剧中人物管理器查询剧中人物数据存款和储蓄。要是剧中人物存储在数据库中,那么对于种种须要须求拜望几个数据库的状态,您能够轻巧地湮灭访谈八个数据库。施工方案是安顿剧中人物管理器以在 Cookie 中缓存剧中人物数据:

<roleManager enabled="true" cacheRolesInCookie="true" />

你可以动用另外<roleManager> 属性调节角色 Cookie 的特色 — 例如,Cookie 应维持有效的依期(以致剧中人物管理器由此回到角色数据库的功能)。剧中人物 Cookie 暗中同意情形下是经过具名和加密的,因而安全危害就算不为零,但也具备缓慢解决。

www0907com 11重临页首

视图状态:无声的本性杀手

从某种意义上说,视图状态是一向最光辉的事情。终究,视图状态使得页面和控件能够在回发之间维持状态。因而,您不用像在观念的 ASP 中那么编写代码,防止止在单击按键时文本框中的文本消失,或在回发后重新查询数据库和另行绑定 DataGrid。

可是视图状态也许有劣势:当它拉长得过大时,它便成为贰个冷清的属性徘徊花。有个别控件(举例文本框)会基于视图状态作出相应判断。其余控件(特别是 DataGrid 和 GridView)则基于呈现的新闻量鲜明视图状态。倘使 GridView 展现200 或 300 行数据,小编会举步维艰。纵然 ASP.NET 2.0 视图状态大概是 ASP.NET 1 x 视图状态的四分之二高低,一个倒霉的 GridView 也得以轻易地将浏览器和 Web 服务器之间的连年的立竿见影带宽收缩 50% 或越多。

您能够透过将 EnableViewState 设置为 false 来关闭单个控件的视图状态,但有个别控件(特别是 DataGrid)在不可能选择视图状态时会失去一些意义。调整视图状态的更佳建设方案是将其保存在服务器上。在 ASP.NET 1.x 中,您可以重写页面包车型大巴 LoadPageStateFromPersistenceMedium 和 SavePageStateToPersistenceMedium 方法并按您喜欢的章程处理视图状态。图 4 中的代码展现的重写可防卫视图状态保留在隐蔽字段中,而将其保存在对话状态中。当与暗中同意会话状态进度模型一同行使时(即,会话状态存款和储蓄在内部存款和储蓄器中的 ASP.NET 扶助进程中时),在对话状态中存放视图状态更是有效。相反,假使会话状态存款和储蓄在数据库中,则只有测验本事显得在对话状态中保留视图状态会增高恐怕下跌品质。

在 ASP.NET 2.0 中利用同样的措施,不过 ASP.NET 2.0 能够提供更轻便的艺术将视图状态保留在对话状态中。首先,定义一个自定义页适配器,其 GetStatePersister 方法再次来到 .NET Framework SessionPageStatePersister 类的三个实例:

public class SessionPageStateAdapter :
System.Web.UI.Adapters.PageAdapter
{
public override PageStatePersister GetStatePersister ()
{
return new SessionPageStatePersister(this.Page);
}
}

下一场,通过将 App.browsers 文件按以下情势归入应用程序的 App_Browsers 文件夹,将自定义页适配器注册为暗中同意页适配器:

<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.Page"
adapterType="SessionPageStateAdapter" />
</controlAdapters>
</browser>
</browsers>

(您能够将文件命名叫您喜欢的别的名称,只要它的恢弘名叫 .browsers 就能够。)从此,ASP.NET 将加载页适配器并动用重回的 SessionPageStatePersister 以保存全数页面状态,富含视图状态。

接受自定义页适配器的一个毛病是它全局性地效用于应用程序中的每黄金年代页。借使您更乐于将中间部分页面包车型地铁视图状态保留在对话状态中而不保留其余页面包车型大巴视图状态,请使用图 4 中展现的议程。别的,若是用户在同一会话中开创四个浏览器窗口,您使用该办法或然会遇上标题。

www0907com 12归来页首

本文由威尼斯城真人赌钱网站发布,转载请注明来源

关键词: