[MSDN]通过避免下列 10 独常见 ASP.NET 缺陷而网站平稳运作

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

ASP.NET 成功的其中一个由在它们降低了 Web
开发人员的窍门。即便你不是计算机对博士也得编制 ASP.NET
代码。我在工作中遇到的广大 ASP.NET 开发人员都是自学成材的,他们以编辑
C# 或 Visual Basic® 之前还当编制 Microsoft® Excel®
电子表格。现在,他们以编排 Web
应用程序,总的来说,他们所举行的劳作值得表扬。

然和能力随之而来的还有事,即使是经验丰富的 ASP.NET
开发人员也不免会错。在连年底 ASP.NET
项目咨询工作被,我发觉一些错误特别好招缺陷不断有。其中一些错误会影响属性。其他左会制止可伸缩性。有些错误还会见要开发团队耗费宝贵的时日来跟错误和意外的表现。

下面是会招 ASP.NET 生产应用程序的披露过程遭到起问题的 10
单缺陷和可避免它们的计。所有示例均源于自身对实际的营业所构建真正的 Web
应用程序的亲体验,在少数情况下,我会通过介绍 ASP.NET
开发集团于开进程被相遇的片段题材来供有关的背景。

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备受的代码都将运行。虽然看起复杂一点,但它见面避免烦人的荒谬。简单并无连续代表容易维护。

图片 1回到页首

对话和出口缓存

言到输出缓存,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 标头),即使该要都同一个实惠之对话相关联而对提交了
Cookie 中之对话 ID。实际上,ASP.NET
是不管三七二十一以用户从他们协调的对话中切换出并将他们连年到其它会话。

咱俩充分怪,于是从头物色原因。我们先是检查了 Contoso.com
的源代码,让咱深感宽慰之是,问题非以那么。接着,为了确保问题和应用程序宿主以
Web
领域无关,我们只有保留一个服务器在运作,而关闭了拥有其他服务器。问题还有,这并无飞,因为咱们的日记显示匹配的
Set-Cookie 标头绝不见面来星星只不等之服务器。ASP.NET
意外地充分成了再次的对话 ID,这令人难以置信,因为它使用 .NET Framework
RNGCryptoServiceProvider 类生成这些 ID,并且会话 ID 的长可以保证同等的
ID 决不见面变卦两不良(至少在产一个万亿年内未见面扭转两不善)。除此之外,即使
RNGCryptoServiceProvider 错误地好成了更的自由数字,也无法解释 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,我会建议他们禁用内核模式输出缓存。问题一般就会见迎刃而解。如果问题从未缓解,则错误是于代码中。警惕!

图片 2回页首

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
年!这样便会见发生问题,因为要是有人窃取了该身份验证票证,他们就是可以于票据的有效期内采用受害者的身价走访网站。窃取身份验证票证有多种方法

在公无线访问点探测未加密的通信、跨网站编写脚本、以物理方法访受害者的计算机等等
— 因此,向 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) 来检查身份验证 Cookie 的传播响应。Helper
方法是釜底抽薪 ASP.NET 1.1 中其他一个错的主意,如果你运
HttpCookieCollection 的字符串索引生成器来检查无在的
Cookie,此错误会招致伪 Cookie 添加到应中。使用整数索引生成器作为
GetCookieFromResponse 可以缓解该问题。

图片 3回到页首

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

自某种意义上说,视图状态是素最为了不起之事体。毕竟,视图状态让页面和控件能够当回发之间保持状态。因此,您不要像在风俗的
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
中显示的艺术。另外,如果用户在同一会话中创造多只浏览器窗口,您使用该方式可能会见碰到问题。

图片 4返页首

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

ASP.NET 使得以数据库中贮存会话状态变得简单:只需要切换 web.config
中之开关,会话状态就见面轻松地倒到后端数据库。对于当 Web
领域被运作的应用程序来说,这是平等起重点力量,因为它们同意该领域受到的每个服务器共享会话状态的一个公共库。添加的数据库活动降低了么请求的习性,但是可伸缩性的滋长弥补了性能的损失。

这看起还还不错,但是你略微考虑一下下列几碰,情况便见面迥然不同:

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

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

转移句话说,当您运 SQL Server™
会话状态选项时,您于每个请求中都要提交代价(两独数据库访问)—
甚至当与会话状态无关之页面的呼吁中。这会直接指向普网站的吞吐量造成负面影响。

 

图片 5

贪图 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 模型也特别重大。

图片 6回页首

不缓存的角色

以下语句经常出现于 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
默认情况下是经过签字和加密的,因此安全风险则非为零星,但为存有缓解。

图片 7返页首

布文件属性序列化

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”
属性并确保项目我是只是序列化的。否则,将无法展开整的序列化,并且您还以浪费时间来尝试确定安排文件无法工作的原因。

图片 8归来页首

线程池饱和

在实施数据库查询并伺机 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 应用程序都待异步页面。请记住这一点!

图片 9回来页首

模拟和 ACL 授权

以下是一个简练的配备指令,但是于在 web.config
中看到其时都叫我眼前一亮:

<identity impersonate="true" />

夫命令以 ASP.NET
应用程序中启用客户端模拟。它用意味客户端的走访使牌附加到处理要的线程,以便操作系统执行的安全性检查针对的是客户端位使不是帮扶进程身份。ASP.NET
应用程序很少要效法;我的阅历告诉自己,开发人员通常还是出于错误的由来一旦启用模拟的。以下是原因所在。

开发人员经常在 ASP.NET
应用程序中启用模拟,以便可以以文件系统权限来限制对页面的访。如果 Bob
没有翻动 Salaries.aspx
的权柄,则开发人员将会启用模拟,以便可以通过将访问控制列表 (ACL)
设置为拒绝 Bob 的读取权限,阻止 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 *!

图片 10回到页首

不用了信任它 — 请设置数据库的布置文件!

用作同号称顾问,我不时让询问怎么应用程序没有随预想执行。最近,有人打听自己的集团也何
ASP.NET 应用程序只完成请求文档所需要吞吐量(每秒的请求数)的光景
1/100。我们原先所发现的题目是咱当非可知健康运作的 Web
应用程序中发觉的题目特有的 — 和我们具有人当认真对照的训。

咱俩运行 SQL Server Profiler
并监视这应用程序和后端的数据库中的相情况。在一个重不过的案例中,仅仅只是一个按钮单击,就招数据库来了
1,500
多单谬误。您不能够那么构建大性能的应用程序。良好的网布局总是从完美的数据库设计开。不管而的代码的效率来多胜,如果她于编不尽如人意的数据库所牵连,就会见不起作用。

糟糕之数目访问体系布局通常来自下面的一个要么多单地方:

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

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

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

须事先确定问题才会针对那个进行处理。确定数据看问题的不二法门是运作 SQL Server
Profiler
或平等的工具为查看后台正在推行之操作。检查应用程序和数据库里的通信后,性能调整才大功告成。尝试一下
— 您或许会见针对君的发现震惊。

图片 11归来页首

结论

今你曾了解在生成 ASP.NET
生产应用程序过程遭到恐碰到的一对题材及其解决方案了。下一样步是仔细翻看您自己的代码并尝试避免自己于这概述的有些题目。ASP.NET
可能下挫了 Web
开发人员的技法,但是你的应用程序完全产生理由灵活、稳定与高效。请认真考虑,避免出现新手易犯的谬误。


8
提供了一个简便检查列表,您可行使她来避免本文中讲述的短处。您得创造一个像样的安全缺陷检查列表。例如:

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

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

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

若果你重视网站、承载网站的服务器和它所指的后端资源的完整性,则这些题目很重大。

相关文章