ASP.NET Dynamic Data: The table no longer displays after inserting data if it accesses FormView.Controls on the page. Initialized Event

Recently, I got an error for Ninject.Web that it does not work properly with dynamic ASP.NET data. The problem is that when postback (for example, when inserting, deleting, editing an entry), the table is no longer displayed.

Some debugging showed that the problem was caused by the IHttpModule, which recursively iterates through all the controls on the page after its initialization. As soon as this module accesses the Controls get accessor FormView or GridView element, a problem arises. If this type of control is skipped, everything is in order. The following code shows the module:

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); } } 

If this code is modified so that iteration through the child DataBoundControls controls is delayed in the DataBound event, everything is fine. It is displayed by the following code fragment:

  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); } } 

Since I am completely unfamiliar with System.Web.DynamicData, I would like to learn some things in order to better understand how to fix this error:

  • Why is this problem occurring? I mean, this is easy access to access the Controls property.
  • What side effects can the above changes have?
  • Is there enough time to enter the controls after the data event?
  • Do you think this is a valid bug fix for this problem?
+4
source share
1 answer

Of course, bewilderment, as sometimes happens in WebForms with many stages of execution.

Although this is easy access to the Controls property, this property can really do a lot of work to return the child controls. In particular, it cannot return child controls if they are not created, and that creation usually does not take longer in the page life cycle. Therefore, turning to him in InitComplete, the children are ultimately created prematurely before some important Dynamic Data connections occur, as a result of which some controls will be missing. Yes, I understand that the behavior of the final result seems unlikely, so some people prefer the straightforwardness of MVC :)

As an alternative workaround possible, can you try moving the injection from InitComplete to PreLoad? eg.

 page.PreLoad += (src, args) => InjectUserControls(page); 

I am sure that I will consider the problem, although I am not sure that this will cause problems with your KernelContainer.Inject logic. Try it because it is easier than your workaround.

If this does not work, I think your workaround is fine, as it delays the enumeration until the children are created. As for "It's early enough to introduce controls after the data event," I think it depends on what KernelContainer.Inject does and what expectations it has in control state.

+2
source

All Articles