一些debuging表明问题是由IHttpModule引起的,它在初始化后递归遍历页面的所有控件.只要此模块访问Controls属性获取FormView或GridView的访问器,就会出现问题.如果这种类型的控件滑雪,一切都很好.以下代码显示了该模块:
public class NinjectHttpModule : disposableObject,IHttpModule { private HttpApplication httpApplication; public void Init(HttpApplication context) { this.httpApplication = context; this.httpApplication.PreRequestHandlerExecute += this.OnPreRequestHandlerExecute; } private static void InjectUserControls(Control parent) { if (parent == null) { return; } foreach (Control control in parent.Controls) { if (control is UserControl) { // KernelContainer.Inject(control); This is irrelevant for the question. } InjectUserControls(control); } } private void OnPreRequestHandlerExecute(object sender,EventArgs e) { var page = this.httpApplication.Context.CurrentHandler as Page; if (page == null) { return; } KernelContainer.Inject(page); page.InitComplete += (src,args) => InjectUserControls(page); } }
如果更改此代码,以便通过DataBoundControls的子控件的迭代延迟到DataBound事件,一切都很好.由下一个代码段显示:
private static void InjectUserControls(Control parent,bool skipDataBoundControls) { if (parent == null) { return; } if (skipDataBoundControls) { var dataBoundControl = parent as DataBoundControl; if (dataBoundControl != null) { dataBoundControl.DataBound += InjectDataBoundControl; return; } } foreach (Control control in parent.Controls) { if (control is UserControl) { KernelContainer.Inject(control); } InjectUserControls(control,skipDataBoundControls); } } private static void InjectDataBoundControl(object sender,EventArgs e) { var dataBoundControl = sender as DataBoundControl; if (dataBoundControl != null) { dataBoundControl.DataBound -= InjectDataBoundControl; InjectUserControls(dataBoundControl,false); } }
因为我对System.Web.DynamicData完全不熟悉,所以我想知道一些事情,以便更好地了解如何修复这个bug:
>为什么会出现这个问题?我的意思是它只是对Controls属性的简单读取访问.
>上述变化有哪些副作用?
>在数据绑定事件之后注入控件是否仍然足够早?
>您认为这是针对此问题的有效错误修复方法吗?
解决方法
即使它只是对Controls属性的简单读取访问,该属性实际上可以做很多工作来返回子控件.特别是,它不能返回子控件,除非它们已经创建,并且创建通常直到页面生命周期的后期才会发生.因此,通过在InitComplete中访问它,孩子最终会在一些重要的动态数据连接发生之前过早地被创建,导致一些控件丢失.是的,我意识到最终结果行为似乎毫无意义,这就是为什么有些人喜欢MVC的直截了当:)
作为替代可能的解决方法,您可以尝试将注射从InitComplete移动到PreLoad吗?例如
page.PreLoad += (src,args) => InjectUserControls(page);
我很确定这会解决问题,但我不太确定这是否会导致你的KernelContainer.Inject逻辑出现问题.试一试,因为它比你的解决方法更简单.
如果这不起作用,我认为您的解决方法是可以的,因为它会延迟枚举直到创建子项.至于“在数据绑定事件之后是否足够早地注入控件”,我认为这完全取决于KernelContainer.Inject的功能,以及它对控件状态的期望.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。