Welcome to Tech-Review.Org Sign in | Join | Help

.net_2.0

My coding blog entries. Typically will either be more complex coding examples or overcoming product issues / troubleshooting resolutions.
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...

Posted: Tuesday, February 06, 2007 6:34 PM by Jody

Comments

Jody said:

Thanks to Raj off the Forums for responding to my in frustration gonna bump the thread post...

It is a workaround but in my opinion the last thing I want to do is override anything on the render stage.  I guess I could call the base.Render afterwords but I prefer finding my controls on the OnInit phase so they are available everywhere through out the various page events.  None the less Raj did provide a method to do it.  

see the forum threads for discussion....

http://forums.asp.net/thread/1566285.aspx

Here is my code in the Render stage:

protected override void Render(HtmlTextWriter writer) {

Image Image1 = UpdateProgress1.FindControl("Image1") as Image;

if (Image1 != null) {

Image1.ImageUrl = "~/images/loading.gif";

}

base.Render(writer);

}

Check out his website its very informative as well....

http://weblogs.asp.net/rajbk/

# February 10, 2007 1:46 PM

Walt Kraybill said:

I was having the same problem and was able to get the image to appear with code behind (VB) by adding the Image control at PageLoad and removing the IMG tag from the ASP. Your article clued me into the problem - thanks:

Protected Sub Page_Load(ByVal sender As Object, ....)

  Dim oImage as New Image

  oImage.ImageUrl = "ProgressBar.gif"

  UpdateProgress1.Controls.Add(oImage)

End Sub

# January 5, 2008 8:00 AM
New Comments to this post are disabled