RadAjaxManager on UserControl Nested Atop UpdatePanel

4 posts, 0 answers
  1. JD
    JD avatar
    22 posts
    Member since:
    Jul 2013

    Posted 18 Feb 2014 Link to this post

    Hi,

    I work on a large, enterprise application built with many user controls.  The user controls have NO ASCX, they are completely defined at runtime in CS files.  Additionally, when developing user controls for the application and implementing new functionality, I don't have control over the framework or hierarchy of the parent controls which will consume my user controls.  They might be nested 5 layers deep, user control on top of user control.

    I've seen many posts about the perils of using RadAjaxManager with UpdatePanels, but I don't have a choice in the matter and I haven't encountered the same issues others have reported.  So I apologize if this is redundant but I've not seen anything about my scenario or the strange behavior I'm seeing.

    Basically, if a parent up the control hierarchy employs an UpdatePanel, when the AsyncUpload control posts pack (using RadAjaxManager), the ajax response is improperly formatted and the ajax path to the RadAjaxManager target control(s) actually appears in the html markup and that containers child controls are rendered twice.  The html render is completely broken as you can see in the mock up I have included.  I think this may be a bug in RadAjaxManager.  

    I'm including code for 3 files - 3 layers of hierarchy, which demonstrates the issue.

    fileUpload.aspx
    ParentControl.cs (created by fileUpload)
    UploadControl.cs (created by ParentControl) <-- this is the only one I have control over.

    Notes:
    Keep in mind that if we equate this to my situation, UploadControl is the only one I can change, I don't have access to ParentControl or fileUpload.
    In the demo app, the issue only happens if the UpdateMode of the panel in ParentControl.cs is set to Always.  This has something to do with the fact that everything in UloadControl sits on a generic Panel.  If I remove the Panel and just drop the objects in UploadControl directly in the Controls collection, then the ajax render will be messed up regardless of the UpdateMode setting in the ParentControl.  Changing the UpdateMode in the ParentControl is not an option, there are often good reasons why it's set to Always - other children of the parent may rely on that setting.

    As always, thanks in advance,
    JD

    fileUpload.aspx

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="fileUpload.aspx.cs" Inherits="TelerikApp.fileUpload" %>
     
    <!DOCTYPE html>
     
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
         
        </div>
        </form>
    </body>
    </html>

    fileUpload.aspx.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Telerik.Web.UI;
    using TelerikApp.Controls;
     
    namespace TelerikApp
    {
        public partial class fileUpload : System.Web.UI.Page
        {
            protected WebControl _DivPageContent = new WebControl(HtmlTextWriterTag.Div);
     
     
            protected void Page_Init(object sender, EventArgs e)
            {
     
                this._DivPageContent.Controls.Add((Control)(new ParentControl()));
                _DivPageContent.ID = "_DivPageContent";
                this.form1.Controls.Add(_DivPageContent);
     
                RadAjaxManager manager = new RadAjaxManager();
                manager.ID = "RadAjaxManager1";                
                this.form1.Controls.Add(manager);              
            }
        }
    }


    ParentControl.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Telerik.Web.UI;
     
    namespace TelerikApp.Controls
    {
        public class ParentControl : WebControl
        {
            private RadButton _someButton = new RadButton();
            UpdatePanel _update = new UpdatePanel();
            UploadControl _upLoad = null;
     
            protected override void OnInit(EventArgs e)
            {
                this._someButton.ID = "SomeButton";
                this._someButton.Text = "Click Me";
                this._someButton.AutoPostBack = true;
                this._someButton.Click += _someButton_Click;
     
                this._update.ID = "myUpdatePanel";
                this._update.UpdateMode = UpdatePanelUpdateMode.Always; //.Conditional Fixes issue in some cases
     
                this._upLoad = new UploadControl();
                this._upLoad.ID = "myUpLoadControl";
     
                this._update.ContentTemplateContainer.Controls.Add(this._upLoad);
     
                this._update.ContentTemplateContainer.Controls.Add(new LiteralControl("<br/><br/>More Controls on the UpdatePanel<br/>"));
                this._update.ContentTemplateContainer.Controls.Add(this._someButton);
                this.Controls.Add(_update);
     
                base.OnInit(e);
            }
     
            void _someButton_Click(object sender, EventArgs e)
            {
                //any silly functionality
                if (this._someButton.ToolTip == "") this._someButton.ToolTip = "0";
                int count = int.Parse(this._someButton.ToolTip) + 1;
                this._someButton.Text = "You've Clicked " + count.ToString() + " times";
                this._someButton.ToolTip = (count).ToString();
            }
        }
    }


    UploadControl.cs
    using System;
    using System.Threading;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Telerik.Web.UI;
     
    namespace TelerikApp.Controls
    {
        public class UploadControl : WebControl
        {
            private RadButton _btUpload = new RadButton();
            private RadAsyncUpload _fiInput = new RadAsyncUpload();
            private DropDownList _DdDocumentTypes = null;
            private Label _lbl = new Label();
            private RadAjaxManager _ajaxManager = new RadAjaxManager();
            private Panel _DocUploadControlPanel = new Panel();
            private RadAjaxLoadingPanel _ajaxLoadingPanel = null;
     
            protected override void OnInit(EventArgs e)
            {
                base.OnInit(e);
     
                ScriptManager scriptManager = new ScriptManager();
                scriptManager.ID = "scriptManager";
                this.Page.Form.Controls.Add(scriptManager);
     
                this._lbl.ID = "_lbl";
                this._lbl.Text = "";
     
                this._DocUploadControlPanel.ID = "_DocUploadControlPanel";
                this._DocUploadControlPanel.CssClass += " docUploadControlPanel";
                this._DocUploadControlPanel.Style.Add("display", "inline-block");
                this._DocUploadControlPanel.BackColor = System.Drawing.Color.LightBlue;
     
                this._DdDocumentTypes = new DropDownList();
                this._DdDocumentTypes.ID = "DDLDocumentTypes";
                this._DdDocumentTypes.EnableViewState = false;
                this._DdDocumentTypes.AutoPostBack = false;
                this._DdDocumentTypes.Items.Add(new ListItem("type1"));
                this._DdDocumentTypes.Items.Add(new ListItem("type2"));
     
                this._ajaxLoadingPanel = new RadAjaxLoadingPanel();
                this._ajaxLoadingPanel.ID = "_ajaxLoadingPanel";
                this._ajaxLoadingPanel.Transparency = 50;
                this._ajaxLoadingPanel.BackColor = System.Drawing.Color.DarkGray;
                this._ajaxLoadingPanel.Skin = "Default";
     
                this._fiInput.ID = "FileInput";
                this._fiInput.MultipleFileSelection = Telerik.Web.UI.AsyncUpload.MultipleFileSelection.Disabled;
                this._fiInput.FileUploaded += FileUploaded;
     
                this._btUpload.ID = "UploadButton";
                this._btUpload.CausesValidation = false;
                this._btUpload.Text = "Upload";
     
                DataBind();
     
                this._DocUploadControlPanel.Controls.Add(this._ajaxLoadingPanel);
                this._DocUploadControlPanel.Controls.Add(this._DdDocumentTypes);
                this._DocUploadControlPanel.Controls.Add(this._fiInput);
                this._DocUploadControlPanel.Controls.Add(this._btUpload);
                this._DocUploadControlPanel.Controls.Add(new LiteralControl("<br/>"));
                this._DocUploadControlPanel.Controls.Add(this._lbl);
                this.Controls.Add(_DocUploadControlPanel);
     
            }
     
            protected override void OnPreRender(EventArgs e)
            {
                base.OnPreRender(e);
                _ajaxManager = RadAjaxManager.GetCurrent(Page);
                _ajaxManager.AjaxSettings.AddAjaxSetting(this._btUpload, this._DocUploadControlPanel, this._ajaxLoadingPanel);
                //_ajaxManager.AjaxSettings.AddAjaxSetting(_btUpload, _lbl);
     
            }
     
            private void FileUploaded(object sender, FileUploadedEventArgs e)
            {
                Thread.Sleep(2000);
                _lbl.Text = "UPLOADED " + e.File.FileName + " TYPE: " + this._DdDocumentTypes.SelectedValue;
                _lbl.BackColor = System.Drawing.Color.LightGreen;
            }
     
        }
     
    }


     

  2. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 21 Feb 2014 Link to this post

    Hello Justyn,

    I reviewed the provided code and noticed that you are loading the inner UpdateControls user control into the UpdatePanel in the ParentControl.cs. Note that in this case all the child in the controls tree should perform AJAX request and adding  RadAjaxManager settings for the controls in the inner UpdateControl.cs would not be necessary. Could you please let me know if you are adding this settings for some specific reason? Try to remove them and verify how it goes.

    Regards,
    Maria Ilieva
    Telerik
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the UI for ASP.NET AJAX, subscribe to the blog feed now.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. JD
    JD avatar
    22 posts
    Member since:
    Jul 2013

    Posted 24 Feb 2014 in reply to Maria Ilieva Link to this post

    There are two reasons the ajaxManager settings are needed.
    1. I don't know if the parent control will have an update panel.  The fileUpload control will be consumed by many parent controls - most of which DON'T have an UpdatePanel.  If there is a common pattern to, say walk the hierarchy and behave differently based on what is found higher up, I'd like to see that.  But that still wouldn't solve #2.
    2.  The upload should work in a uniform manner, regardless of where it resides - with the upload panel and spinner doing the same things.  Since this behavior is declared in the RadAjaxManager.AjaxSettings, it would appear that this control is a requirement for consistent look and feel.

    Thanks,
    Justyn


  5. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 27 Feb 2014 Link to this post

    Hi Justyn,

    Could you please try replacing the RadAjaxManager settings with regular asp UpdatePanel in the inner level as you are using in the upper pages and verify if this makes any difference? Testing if the nested UpdatePanels behaves the same will help us determine if the issue is directly caused by the RadAjaxManager or basically appears due to the nested logic of the Ajax requests.

    Regards,
    Maria Ilieva
    Telerik
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the UI for ASP.NET AJAX, subscribe to the blog feed now.
Back to Top