Legends 足球Never Die

   
明日要讲的主人公,是LOL界最宏大的人,而且从不之一。近期隔三差五听到legends
never
die那首歌,总会想起那些在准决赛舞台上哭泣的男孩,即便她曾经21了,但我想,输掉比赛的那一刻,他必定就是个子女,无助、悲伤、懊丧、不甘这么些所有类似于愁肠的心理交织在他左右,彻底粉碎了她那颗曾经最为强大的心。很五个人说,三十年河东,三十年河西,曾经的李相赫打哭那么四个人,此刻然则是物换星移,主演也换了私家而已。对于观众而言,没有人愿意只见到一个朝代,人们无形中里面,激荡的就是对抗,抗拒一个神话最好的主意——可是就是开创一个新的神话,因为只有一个神话终究是会令人厌倦的。

陈设文件属性种类化

ASP.NET 2.0
配置文件服务为维持每个用户的情状(例如个性化首选项和言语首选项)的题目提供了一个现成的缓解方案。要采取布置文件服务,您可以定义一个
XML 配置文件,其中饱含要保存的意味单个用户的性能。然后,ASP.NET
编译一个分包相同属性的类,并由此丰裕到页的配置文件属性提供对类实例的强类型访问。

安排文件灵活性很强,它竟然同意将自定义数据类型用作配置文件属性。可是,其中却存在一个题目,我亲眼看到该问题造成开发人士出差错。
6

包罗一个名为 Posts 的简易类,以及将 Posts
用作计划文件属性的配备文件定义。不过,该类和该配置文件在运作时会发生意料之外的行为。您能找出其中的来由呢?

题材在于 Posts 包含一个名为 _count
的个人字段,该字段必须开展连串化和反体系化,才能一心冰冻和重复冻结类实例。但是
_count 却从没通过连串化和反系列化,因为它是私家的,而且默许情形下
ASP.NET 配置文件管理器使用 XML
连串化对自定义类型进行种类化和反系列化。XML
连串化程序将忽略非公共成员。因而,会对 Posts
的实例实行体系化和反连串化,可是每一回反体系化类实例时,_count 都会重设为
0。

一种缓解方案是使 _count
成为公共字段而非私有字段。另一种缓解方案是使用集体读/写属性封装
_count。最佳解决方案是将 Posts 标记为可种类化(使用
SerializableAttribute),并将配置文件管理器配置为运用 .NET Framework
二进制种类化程序对类实例举办连串化和反体系化。该解决方案可以维持类本身的规划。与
XML
体系化程序差异的是,二进制系列化程序种类化字段,而不论是或不是可以访问。
7

呈现 Posts 类的修复版本并鼓起呈现了转移的附带配置文件定义。

您应该牢记的少数是,假如你使用自定义数据类型作为配置文件属性,并且该数据类型具有必须连串化才能完全系列化类型实例的非公共数据成员,则在性能讲明中接纳serializeAs=”Binary”
属性并保障项目我是可体系化的。否则,将不能进展全体的种类化,并且您还将浪费时间来品尝确定陈设文件不能工作的原由。

足球 1归来页首

   
如若把faker的事迹换来任何领域,他都应该是我们的榜样,他既谦虚又傲慢;忠于自己的老东家不丢掉不放弃;失败时候首先找自己原因,而不是一贯责怪队友;他有礼数,话纵然不多,但充满智慧;他尊重她的每一个挑战者,充满职业精神。像她这么的人,你要精晓,也才21岁。传奇在于拼搏,至高的美观不是各种人都能企及的,强如UZI,pray,没有人困惑他们的实力,去终不可能防止于无冠。拼搏,不仅是电竞精神,更是人活在大地应有的情态。Legends
never die,嗯,那就是传奇永不灭,那句话肯定是为faker量身定做的。

上边是会招致 ASP.NET 生产应用程序的发布进程中现身问题的 10
个毛病以及可幸免它们的主意。所有示例均来源于自身对实在的合营社构建真正的 Web
应用程序的亲自体验,在一些情形下,我会通过介绍 ASP.NET
开发公司在开发进程中相遇的一些题材来提供相关的背景。

   
说实话,游戏只是我的一个个人爱好的一边,他不会是生活的整个,但是可能在某一须臾间,在某一个得以打动到技惊四座的moment,在一个足以让我们呐喊和流泪的minute,它就是中外。

原文:http://www.microsoft.com/china/msdn/library/webservices/asp.net/WebAppFollies.mspx?mfr=true

   
最后部分话,送给自己原先的战友们,比起体育的篮球足球网球之类,LOL一定有走到尽头的那一天,人都有透支自己喜好的那一天,一个游戏终究只可以承载一代人的回顾,老玩家的消散,没有新鲜血液的融入,更面临新兴娱乐的挑衅,那就是他脚下的困境。有人说,玩lol的人少了,是因为刚初阶接触这批游戏的人都老了,他们或许都有了祥和的行事和家中,有了生活中更值得讲究的东西和更值得爱的人。世界的百分之百事物,都是在动态发展着的,盛衰之势常有,大家不必惋惜,他将离大家而去,逐渐淡出大家的视野和生活。但作为体育的电子竞赛,其动感是绝不会倒下的。这才是legends
never die的末尾奥义,或许。

毫不完全信任它 — 请设置数据库的配备文件!

用作一名顾问,我每每被打探为啥应用程序没有按预期执行。方今,有人打听自己的团体为何ASP.NET 应用程序只达成请求文档所需吞吐量(每秒的请求数)的几乎1/100。大家在此从前所发现的题材是大家在无法健康运转的 Web
应用程序中发现的题目特有的 — 和大家所有人应该认真对待的教训。

俺们运行 SQL Server Profiler
并监视此应用程序和后端的数据库之间的并行处境。在一个更极致的案例中,仅仅只是一个按钮单击,就导致数据库暴发了
1,500
八个错误。您无法那么构建高性能的应用程序。良好的种类布局总是从理想的数据库设计初步。不管你的代码的成效有多高,若是它被编辑不好的数据库所牵连,就会不起功能。

不佳的数额访问连串布局常常来自上边的一个或多个地点:

拙劣的数据库设计(通常由开发人员设计,而不是数据库管理员)。

DataSets 和 DataAdapters 的使用 — 尤其是 DataAdapter.Update,它适用于 Windows 窗体应用程序和其他胖客户端,但是对于 Web 应用程序来说通常不理想。

具有拙劣编制计算程序、以及执行相对简单的操作需消耗很多 CPU 周期的设计糟糕的数据访问层 (DAL)。

必须先确定问题才能对其进行处理。确定数据访问问题的措施是运行 SQL Server
Profiler
或一致的工具以查看后台正在实施的操作。检查应用程序和数据库之间的通讯之后,性能调整才已毕。尝试一下
— 您或许会对你的觉察震惊。

足球 2回到页首

   
跟所有的体育运动一样,电子竞赛的魅力是伟大的。老话说“音乐不分国界”,其实具有具有感染力的东西都是如此,电竞也不例外。再狭隘的民族主义者也无从否认Faker对LOL的贡献和意义,我们既然喜欢比赛,就该学会分享高品位的竞赛。队员的国籍所属并无法更改比赛自己的脍炙人口程度,一味鼓吹血统论只可以让LPL陷入倒退的窘境。有人说,SKT终于是在鸟巢被三星给击倒了,他们的朝代也终于是终止了,于是理所应当的,Faker也是跌下了神坛,那终究是王朝的宿命,也是竞赛的魅力所在。没有人能永远鹤立鸡群,没有人能强盛,有的直接都是强者居上,新的笔录和新的神话再持续被刷新和开创,同时,那也是竞技将一贯留存和缕缕上扬更上一层楼的案由所在。

SQL Server 会话状态:另一个性能杀手

ASP.NET 使得在数据库中储存会话状态变得简单:只需切换 web.config
中的开关,会话状态就会轻松地移动到后端数据库。对于在 Web
领域中运作的应用程序来说,那是一项根本职能,因为它同意该领域中的每个服务器共享会话状态的一个公共库。添加的数据库活动下落了单个请求的性质,可是可伸缩性的加强弥补了性能的损失。

那看起来都还不错,可是你略微考虑一下下列几点,情状就会有所分歧:

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

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

换句话说,当您使用 SQL Server™
会话状态选项时,您在种种请求中都要付出代价(几个数据库访问)—
甚至在与会话状态无关的页面的伏乞中。那会直接对全部网站的吞吐量造成负面影响。

 

足球 3

图 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 模型却很关键。

足球 4归来页首

   
但对于,faker而言,他绝没有倒下。作为一个出道就终端,而且在其领域登上世界之巅的人,世界历史上也找不出好多少个,所以她肯定是万幸的那几个,中国人笃信“天选之人”,认为“命由天定”,强如孟子,开篇也是“天将降大任于是人也”。假若有,那么李相赫他必然是。但我们驾驭,电子竞赛是实力说话,空谈理想,一定会让祥和距离最初的轨迹。出道的第四个赛季,也就是获取最高的得体后,faker他遭碰到了巨大的挫折和退步,他的私家情形首回有了起降,随之他的武力也分崩离析,最终留下来的,唯有苦苦持之以恒的他和他的亲密无间战友bengi,那一个王的女婿。接下来的故事也许我们都驾驭了,卷土重来的SKT,又三番五次两年囊括了S体系赛和大约拥有大大小小赛事的光荣。可是,二零一九年,他们又倒下了,但必然,今年faker的表演相对不止算职业生涯的第二春,应该只可以用精妙绝伦来形容。作为曾经跌落过神坛的相公,没有怎么比这一遍更能让他倍感轻松和无限的恬静了,他早已经历过一次大的败诉,那四回,他只须要不停学习,以更成熟的态势归来。因为假使她是faker,他就绝不会倒下。

模拟和 ACL 授权

以下是一个简练的布局指令,不过每当在 web.config
中见到它时都让自身耳目一新:

<identity impersonate="true" />

此命令在 ASP.NET
应用程序中启用客户端模拟。它将意味客户端的拜会令牌附加随处理请求的线程,以便操作系统执行的安全性检查针对的是客户端身份而不是帮忙进度身份。ASP.NET
应用程序很少要求效法;我的经历告诉我,开发人员寻常都是出于错误的原因此启用模拟的。以下是原因所在。

开发职员日常在 ASP.NET
应用程序中启用模拟,以便可以选择文件系统权限来限制对页面的拜会。如若 Bob没有翻动 Salaries.aspx
的权柄,则开发人士将会启用模拟,以便可以透过将访问控制列表 (ACL)
设置为拒绝 鲍伯 的读取权限,阻止 鲍伯(Bob) 查看
Salaries.aspx。可是存在以下隐患:对于 ACL 授权来说,模拟是不要求的。在
ASP.NET 应用程序中启用 Windows 身份验证时,ASP.NET 会活动为呼吁的每个
.aspx 页面检查 ACL
并拒绝没有读取文件权限的调用者的央浼。即使禁用了效仿,它仍会这么操作。

局地时候需求表明模拟的客观。可是你寻常可以用理想的宏图来防止它。例如,假定
Salaries.aspx
在数据库中查询只有管理人员才能精通的工薪音讯。通过模拟,您可以运用数据库权限拒绝非管理人士查询薪俸数额的力量。或者您可以不考虑模拟,并且通过为
Salaries.aspx 设置 ACL
以使非管理人员不抱有读取权限,从而限制对薪俸多少的访问。后一种办法提供的习性更佳,因为它完全幸免了效仿。它也消除了不须求的数据库访问。为何查询数据库仅出于安全原因被拒绝?

顺便说一下,我一度协理对一个传统的 ASP
应用程序举行故障排除,该应用程序由于内存占用不受限制而定期重新开动。一个从未有过经历的开发人士将对象
SELECT 语句转换成了 SELECT
*,而并未设想要查询的表包涵图像,这么些图像很大而且数量很多。问题由于未检测到内存泄漏而恶化。(我的托管代码领域!)多年来运转正常的应用程序开端突然止住工作,因为从前重返一两千字节数码的
SELECT
语句现在却再次来到了几兆字节。倘若再拉长不丰硕的版本控制,开发团队的生存将只好“亢奋起来”—
那里所谓的“亢奋”,就犹如当您在夜幕要睡觉时,还只可以望着你的孩子玩令人怨入骨髓的足球游戏一样。

力排众议上,传统的内存泄漏不会发出在一点一滴由托管代码组成的 ASP.NET
应用程序中。但是内存使用量不足会通过强制垃圾收集更频仍地发生而影响属性。尽管是在
ASP.NET 应用程序中,也要当心 SELECT *!

足球 5回去页首

未缓存的角色

以下语句经常出现于 ASP.NET 2.0 应用程序的 web.config 文件以及介绍
ASP.NET 2.0 角色管理器的示范中:

<roleManager enabled="true" />

但正如以上所示,该语句实在会对性能暴发强烈的负面影响。您知道干什么吗?

默许情形下,ASP.NET 2.0
角色管理器不会缓存角色数据。相反,它会在历次要求规定用户属于哪个角色(若是有)时参考角色数据存储。那意味着假设用户通过了身份验证,任何利用角色数据的页(例如,使用启用了平安减少设置的网站图的页,以及采用web.config 中基于角色的 URL
指令展开走访受到限制的页)将导致角色管理器查询角色数据存储。如果角色存储在数据库中,那么对于每个请求要求拜访四个数据库的图景,您能够轻松地解除访问八个数据库。解决方案是布局角色管理器以在
库克ie 中缓存角色数据:

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

您可以选用任何<roleManager> 属性控制角色 Cookie 的特点 —
例如,Cookie
应维持有效的限期(以及角色管理器因而回到角色数据库的频率)。角色 库克(Cook)ie
默许景况下是通过签字和加密的,由此安全风险即使不为零,但也具备缓解。

足球 6回到页首

Forms 身份验证票证生存期

您能找出以下代码的题材吗?

FormsAuthentication.RedirectFromLoginPage(username, true);

此代码看似小问题,但不可能在 ASP.NET 1.x
应用程序中应用,除非应用程序中任何地方的代码抵消了此语句的负面成效。假使您不可能确定原因,请继续阅读。

FormsAuthentication.RedirectFromLoginPage 执行八个义务。首先,当
FormsAuthenticationModule
将用户重定向到登录页时,FormsAuthentication.RedirectFromLoginPage
将用户重定向到他们本来请求的页面。其次,它揭露一个身份验证票证(平时带领在
Cookie 中,而且在 ASP.NET 1.x 中老是辅导在 Cookie
中),这一个单子允许用户在约定的一段时间内保持已因而身份验证状态。

题材就在于这些时刻段。在 ASP.NET 1.x 中,向 RedirectFromLoginPage
传递另一个为 false 的参数会时有发生一个暂时身份验证票证,该票证默许处境下在
30 分钟之后到期。(您可以应用 web.config 的 元素中的 Timeout
属性来更改超时期限。)然则,传递另一个为 true
的参数则会生出一个千古身份验证票证,其有效期为 50
年!那样就会暴发问题,因为假若有人窃取了该身份验证票证,他们就足以在票据的有效期内尔y用受害者的身价访问网站。窃取身份验证票证有多种办法

在国有有线访问点探测未加密的通讯、跨网站编写脚本、以物理方法访问受害者的微机等等
— 由此,向 RedirectFromLoginPage 传递 true
比禁用你的网站的安全性好持续多少。幸运的是,此问题已经在 ASP.NET 2.0
中收获通晓决。现在的 RedirectFromLoginPage 以同样的点子收受在 web.config
中为临时和永远身份验证票证指定的超时。

一种缓解方案是永不在 ASP.NET 1.x 应用程序的 RedirectFromLoginPage
的首个参数中传送
true。然则那不切实际,因为登录页的特色一般是带有一个“将自我保持为记名状态”框,用户可以选中该框以接受永久而不是暂时身份验证
Cookie。另一种缓解方案是使用 Global.asax(假使你愿意的话,也足以行使
HTTP 模块)中的代码段,此代码段会在蕴藏永久身份验证票证的 库克(Cook)ie
再次来到浏览器从前对其展开改动。


3

包涵一个这么的代码段。假设此代码段位于 Global.asax 中,它会修改传出永久
Forms 身份验证 Cookie 的 Expires 属性,以使 库克ie 在 24
时辰后过期。通过改动注释为“新的过期日期”的行,您可以将过期设置为您喜爱的其余日期。

你或许会认为奇怪,Application_EndRequest 方法调用本地 Helper 方法
(GetCookieFromResponse) 来检查身份验证 Cookie 的散播响应。Helper
方法是缓解 ASP.NET 1.1 中另一个荒谬的不二法门,若是你使用
Http库克(Cook)ieCollection 的字符串索引生成器来检查不设有的
库克(Cook)ie,此错误会促成虚假 Cookie 添加到响应中。使用整数索引生成器作为
GetCookieFromResponse 可以缓解该问题。

足球 7回来页首

不过与力量随之而来的还有权利,即便是经验足够的 ASP.NET
开发人士也难免会出错。在连年的 ASP.NET
项目咨询工作中,我发觉某些错误特别不难造成缺陷不断发出。其中一些错误会潜移默化属性。其他错误会抑制可伸缩性。有些错误还会使支付公司开支宝贵的年华来跟踪错误和意外的行为。

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

从某种意义上说,视图状态是一直最了不起的事情。毕竟,视图状态使得页面和控件能够在回发之间保持状态。由此,您不要像在传统的
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

中突显的点子。其余,要是用户在同一会话中开创七个浏览器窗口,您使用该办法或者会遇上题目。

足球 8回到页首

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
中的代码都将运行。纵然看起来复杂一点,但它会防止烦人的谬误。简单并不总是代表简单维护。

足球 9归来页首

结论

近年来您曾经通晓在生成 ASP.NET
生产应用程序进度中可能遇见的一些题材及其解决方案了。下一步是精心查看您自己的代码并尝试防止自己在此概述的有些题材。ASP.NET
可能下落了 Web
开发人士的秘诀,但是你的应用程序完全有理由灵活、稳定和飞跃。请认真考虑,防止出现新手易犯的荒谬。


8

提供了一个大致检查列表,您能够利用它来避免本文中讲述的弱点。您能够创立一个好像的安全缺陷检查列表。例如:

您是否已经对包含敏感数据的配置节进行加密?

您是否正在检查并验证在数据库操作中使用的输入,是否使用了 HTML编码输入作为输出?

您的虚拟目录中是否包含具有不受保护的扩展名的文件?

只要您珍爱网站、承载网站的服务器以及它们所依靠的后端资源的完整性,则那些题材万分重大。

对话和输出缓存

谈到输出缓存,ASP.NET 1.1 和 ASP.NET 2.0
都存在一个神秘的题材,该问题会潜移默化在 Windows Server™ 2003 和 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 标头),尽管该请求已经与一个有效的对话相关联并且正确提交了
库克ie 中的会话 ID。实际上,ASP.NET
是随意将用户从她们自己的对话中切换出去并将她们一连到其余会话。

俺们很好奇,于是从头搜索原因。我们首先检查了 Contoso.com
的源代码,让我们觉得欣慰的是,问题不在那。接着,为了确保问题与应用程序宿主在
Web
领域非亲非故,大家只保留一个服务器在运转,而倒闭了所有其他服务器。问题如故存在,那并不奇怪,因为大家的日志展现匹配的
Set-Cookie 标头绝不会来自四个不等的服务器。ASP.NET
意外地生成了重新的对话 ID,那令人猜疑,因为它选择 .NET Framework
RNGCrypto瑟维斯(Service)(Service)Provider 类生成那几个 ID,并且会话 ID 的尺寸可以有限支撑同等的
ID 决不会转移两回(至少在下一个万亿年内不会生成四回)。除此之外,即便RNGCrypto瑟维斯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
2003,我会提议她们禁用内核形式输出缓存。问题普通就会解决。如若问题从未缓解,则错误存在于代码中。警惕!

足球 10再次回到页首

线程池饱和

在实践数据库查询并等候 15
秒或更长日子来获取重回的询问结果时,我时常对看到的实际的 ASP.NET
页数感到非凡诧异。(我也拭目以待了 15
分钟才来看查询结果!)有时,延迟是由于重返的数据量很大而招致的不可防止的不得已结果;而有时,延迟则是由于数据库的设计不好导致的。但无论是什么原因,长日子的数据库查询或其余项目标长日子
I/O 操作在 ASP.NET 应用程序中都会促成吞吐量的下落。

关于那个题目本身原先曾经详尽地描述过,所以在此就不再作过多的辨证了。我只说一点就够了,ASP.NET
依赖于个其他线程池处理请求,倘使持有线程都被占用来等待数据库查询、Web
服务调用或其他 I/O
操作达成,则在某个操作完结而且释放出一个线程以前,其余请求都无法不排队等候。当呼吁排队时,性能会急剧下落。倘诺队列已满,则
ASP.NET 会使随后的哀告失败并出现 HTTP 503 错误。那种气象不是我们盼望在
Web 生产服务器的生育应用程序上所乐见的。

缓解方案非异步页面莫属,那是 ASP.NET 2.0
中最佳却不为人知的功效之一。对异步页面的请求从一个线程上开首,可是当它开首一个
I/O 操作时,它将回到该线程以及 ASP.NET 的 IAsyncResult
接口。操作已毕后,请求通过 IAsyncResult 布告 ASP.NET,ASP.NET
从池中提取另一个线程并形成对请求的处理。值得注意的是,当 I/O
操作爆发时,没有占用线程池线程。那样能够通过阻止其余页面(不履行较长的
I/O 操作的页面)的呼吁在队列中伺机,从而明确地增进吞吐量。

你可以在 MSDN®Magazine 的 2005 年 10
月刊
中读书有关异步页面的装有讯息。I/O
绑定而不是电脑绑定且需求很长日子实施的任何页面很有可能成为异步页面。

当自身将关于异步页面的音信告知开发人员时,他们日常回答“那正是太棒了,但是本人的应用程序中并不必要它们。”对此我答复说:“你们的其余页面须要查询数据库吗?它们调用
Web 服务啊?您是还是不是业已检查 ASP.NET
性能计数器中有关排队请求和平均等待时间的总计音信?即便你的应用程序至今运行正常化,可是随着您的客户规模的增进,应用程序的载重可能会大增。”

实际,绝大部分实在的 ASP.NET 应用程序都要求异步页面。请记住那或多或少!

足球 11回到页首