【发布时间】:2011-06-28 23:32:01
【问题描述】:
目前,我们所有的跟踪/分析代码都在一个用户控件 (ascx) 中。我们喜欢这样,因为使用我们的 CMS,我们可以将控件放在任何需要跟踪的页面上。
现在的问题是用户可能会无意中将控件放在可能已经包含它的页面上。例如:我们在母版页上包含控件 - 然后在从该母版继承的页面上再次包含。
在呈现页面时确保用户控件仅使用一次的最佳方法是什么?
【问题讨论】:
标签: asp.net user-controls
目前,我们所有的跟踪/分析代码都在一个用户控件 (ascx) 中。我们喜欢这样,因为使用我们的 CMS,我们可以将控件放在任何需要跟踪的页面上。
现在的问题是用户可能会无意中将控件放在可能已经包含它的页面上。例如:我们在母版页上包含控件 - 然后在从该母版继承的页面上再次包含。
在呈现页面时确保用户控件仅使用一次的最佳方法是什么?
【问题讨论】:
标签: asp.net user-controls
这在很大程度上取决于您团队的组成。对于许多团队来说,“最佳”方式只是采用仅包含对母版页进行控制的策略。
不过,如果您不相信您的开发人员会遵守此规则,那么还有更多技术解决方案。例如,控件可以在呈现时设置每个请求标志,并每次检查该标志以确保它尚未在该请求上呈现。如果它已经在给定的请求上呈现,它就不会重新呈现。
【讨论】:
除了循环所有控件及其父/子之外,别无他法。
例如:
Public Module ExtensionMethods
<Runtime.CompilerServices.Extension()> _
Public Function FindControlRecursively(ByVal parentControl As System.Web.UI.Control, ByVal controlType As Type) As System.Web.UI.Control
If parentControl.GetType = controlType Then
Return parentControl
End If
For Each c As System.Web.UI.Control In parentControl.Controls
Dim child As System.Web.UI.Control = FindControlRecursively(c, controlType)
If child IsNot Nothing Then
Return child
End If
Next
Return Nothing
End Function
End Module
你可以这样检查:
If Not FindControlRecursively(Me.Page.Master, GetType(UC_Status)) Is Nothing Then
'thow exception or whatever'
End If
注意:所有未测试
【讨论】:
HttpContext 类有一个 Items 集合,只要正在处理当前请求,您就可以对其进行写入和读取。如果您只是将控件放到页面上,您唯一能做的就是让控件本身通过在 HttpContext.Current.Items 集合中设置一个标志来检查它是否已加载,如果它已经加载,请不要'不渲染输出。如果您想聪明地只加载一次,您可以编写一个辅助/静态方法来加载控件(比如放入开发人员拖放到页面上的占位符控件),而不是将控件放到页面上。然后辅助方法可以使用 HttpContext 来确定是否加载控件。
【讨论】:
添加时,您可能会遍历页面上的控件。如果存在,则不要添加。
【讨论】:
由于这是一个设计时问题,除了在再次部署之前测试它添加到的页面之外,您无能为力。
如果这是在运行时完成的,您可以迭代控件并查找相同的类型。如果找到则删除。
【讨论】: