Beware the UpdateProgress control:
There is a single UpdateProgress control on the page. as such:
<ajax:UpdateProgress ID="UpdateProgress1" runat="server" DisplayAfter="100" >
<ProgressTemplate>
<div style="border:2px solid #0099FF; background-color:#EFEFEF; padding:10px; width:200px; height:20px;">
Updating Panel
</div>
</ProgressTemplate>
</ajax:UpdateProgress>
This works...and the text is displayed
However, when adding a image instead such as:
<ajax:UpdateProgress ID="UpdateProgress1" runat="server" DisplayAfter="100" >
<ProgressTemplate>
<div style="border:2px solid #0099FF; background-color:#EFEFEF; padding:10px; width:200px; height:20px;">
<asp:Image ID="ProgressImage" runat="server" ImageUrl='<%# String.Format("{0}", ResolveUrl("~/Images/admin/green_status.jpg"))%>' /> <--Bad Image URL need to set in Code Behind
</div>
</ProgressTemplate>
</ajax:UpdateProgress>
With above: I can not access the Image Control from code-behind doing any number of nested, recursive, FindControl Methods. However, prior to RC2 / RTM the code I used worked just fine to grab the image control and manipulate it. I need to be able to access the image in code-behind so that I can properly set the url as the image paths are stored in the db using dynamically generated urls to access images on the file system or db. If it the image url is not properly set then a 404 naturally gets injected into the page manipulation and stuff like gridviews dissapearing etc - occur - which is quite frustrating to troubleshoot as all kinds of unexpected behavior occurs (I have mentioned this many times about image not found injecting the actual 404 IIS generated script into a page).
Code I use to find the control:
UpdateProgress1 = (UpdateProgress)GetOptionalControl(skin, "UpdateProgress1");
if (UpdateProgress1 == null) { LE = LE + "UpdateProgress1,"; }
//now get image
updateImage = (Image)this.UpdateProgress1.FindControl("ProgressImage");
if (updateImage != null)
{
updateImage.ImageUrl = ResolveUrl("~/Communities/" + objSectionInfo.Skin + "/Images/progressbar_long_green.gif");
updateImage.AlternateText = "Loading in progress...";
}
else { LE = LE + "ProgressImage FindControl,"; }
or
updateImage = (Image)GetOptionalControl(skin, "ProgressImage");
if (updateImage != null)
{
updateImage.ImageUrl = ResolveUrl("~/Communities/" + objSectionInfo.Skin + "/Images/progressbar_long_green.gif");
updateImage.AlternateText = "Loading in progress...";
}
else { LE = LE + "ProgressImage skinLoad,"; }
or
updateImage = (Image)GetNestedControl(skin, "ProgressImage");
if (updateImage != null)
{
updateImage.ImageUrl = ResolveUrl("~/Communities/" + objSectionInfo.Skin + "/Images/progressbar_long_green.gif");
updateImage.AlternateText = "Loading in progress...";
}
else { LE = LE + "ProgressImage skinLoad,"; }
back end for the GetOptionalControl and GetNestedControl (which I use in scenarios where I have to find a control inside something like a multi-view where one has to dig into the control to explicitly load the child control).
protected Control GetControl(Control skin, string controlID)
{
Control ctlFoundControl = skin.FindControl(controlID);
if (ctlFoundControl == null)
{
throw new Exception("Could not find " + controlID + " in skin!");
}
return ctlFoundControl;
}
public Control GetNestedControl(Control skin, string controlID)
{
Control ctlFoundControl = null;
try
{
ctlFoundControl = base.FindControl(controlID);
}
catch(HttpException)
{
ctlFoundControl = null;
}
return (ctlFoundControl != null) ? ctlFoundControl : GetNestedControl(skin.Controls, controlID);
}
public static Control GetNestedControl(ControlCollection col, string id)
{
foreach (Control c in col)
{
Control child = FindNestedControl(c, id);
if(child !=null)
return child;
}
return null;
}
private static Control FindNestedControl(Control root, string id)
{
if (root.ID != null && root.ID == id)
{
return root;
}
foreach (Control child in root.Controls)
{
Control recurse = FindNestedControl(child, id);
if (recurse != null)
{ return recurse; }
}
return null;
}
//*********************************************************************
/// <summary>
/// GetOptionalControl Method
///
/// Retrieves a control from a skin. If the control cannot be
/// retrieved, DOES NOT throw an exception.
/// </summary>
//*********************************************************************
protected Control GetOptionalControl(Control skin, string controlID)
{
Control ctlFoundControl = skin.FindControl(controlID);
return ctlFoundControl;
}
The same code can find a Panel in the <UpdateProgress> but will not find the <asp: image.... />. And just for the record, I have a collapsible extender that I use the same syntax and able to load the control in code-behind and manipulate the url etc just fine.
With the bad url in the image control the "Get" process gets loaded twice. This is on initial loading of page - being landed on for the first time
Here is with just text in the UpdateProgress Control (expected behavior click to load page)
12/6/2007 10:50:22 AM /admin/Edit+Members/default.aspx 200 GET
22/6/2007 10:50:23 AM/ WebResource.axd 200 GET
With Image in UpdateProgress where the imageurl is bad: Single click to open page (same scenario as above)
12/6/2007 10:56:10 AM /admin/Edit+Members/default.aspx 200 GET
22/6/2007 10:56:11 AM /WebResource.axd 200 GET
12/6/2007 10:56:11 AM /admin/Edit+Members/default.aspx 200 GET
Note the duplicate /admin/Edit+Members/default.aspx - one before and after the WebResource.Axd Get
This is the wrong behavior...
This has to be a bug or something with the UpdateProgress? Again this code worked prior to the Release ....I just didn't realize it was broken because I typically do not have updates that would fall in the timer range I set.
The bigger issue is - and I keep raising this time and time again - and never responses - is that failed 404 requests particulary on images (which can happen just because of client side connectivity issues) - the default 404 IIS message has script it injects into the error page. This gets bundled as a axd request get or post and messes up the DOM and the server-side Sscript Manager... So besides the issue of not being able to get the image control in a UpdateProgress control there still is the issue of figuring out how to exclude axd responses that include 404 errors....in either direction...