Search code examples
c#asp.netupdatepanelajaxcontroltoolkitasyncfileupload

ASP.Net AjaxControlToolkit AsyncFileUpload in update panel that is created in server-side code with master page c#


I have been trawing around all morning trying to get the AsyncFileUpload control from the asp.net AjaxControlToolkit to work in my situation, with no luck.

I have an Ajax enabled page which displays questions to the user, and allows then to go back and forward through the questions without requiring a full-page post back, multiple questions can be displayed on the page and of these questions one or more could be a file upload control. The page uses a masterpage which contains the form element which I have modified as a result of the numerous answers which seem to point to it being the issue.

The page and solution both have references to the AjaxControlToolkit

    <%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>

The code behind that builds the questions is as follows

 1.  private Control _generateControl(FormFields formFieldObject, string questionID) {
 2.         logger.Debug("start of method _generateControl()");
 3.         Control genericControl = _formBLL.getControlForForm(formFieldObject);
 4.         Type typeofcontrol = genericControl.GetType();
 5.         logger.Debug(typeofcontrol.ToString());
 6.  
 7.         HtmlGenericControl controlHolder = new HtmlGenericControl("div");
 8.         controlHolder.ID = _ns + "formfieldHolder_" + formFieldObject.id;
 9.         controlHolder.Attributes.Add("class", _ns + "formfieldHolder");
 10. 
 11.        if (typeofcontrol == typeof(AsyncFileUpload))
 12         {
 13.            #region display question number and question
 14.            Label questionIDLabel = new Label();
 15.            questionIDLabel.CssClass = _ns + "questionIDLabel";
 16.            questionIDLabel.Text = questionID;
 17.            Label questionText = new Label();
 18.            questionText.CssClass = _ns + "questionText";
 19.            questionText.Text = formFieldObject.name;
 20.            #endregion
 21.
 22.            #region add holder for file upload control
 23.            HtmlGenericControl questionControlHolder = new HtmlGenericControl("div");
 24.            questionControlHolder.Attributes.Add("class", _ns + "questionControlHolder");
 25.            genericControl.ID = _ns + "questionControl_" + formFieldObject.id;
 26.            #endregion
 27.
 28.            AsyncFileUpload fuc = (AsyncFileUpload)genericControl;
 29.            fuc.ID = _ns + "questionControl_" + formFieldObject.id;
 30.            fuc.ClientIDMode = ClientIDMode.AutoID;
 31.            fuc.UploadedComplete += fileuploadClick;
 32.            fuc.UploadedFileError += fileuploadError;
 33.            questionControlHolder.Controls.Add(fuc);
 34.
 35.            // add the controls to the holder
 36.            #region add controls to page
 37.            controlHolder.Controls.Add(questionIDLabel);
 38.            controlHolder.Controls.Add(questionText);
 39.            controlHolder.Controls.Add(questionControlHolder);
 40.            #endregion
 41.        }
 42.        return controlHolder;
 43.  }

The control is then added to the placeholder in the aspx page

 <asp:UpdatePanel ID="questionPanel" runat="server" UpdateMode="Conditional">     
    <ContentTemplate>           
        <asp:PlaceHolder ID="QuestionSection" runat="server">             
        </asp:PlaceHolder>
    </ContentTemplate>    
</asp:UpdatePanel>

Following are the methods which are supposed to be called but from Visual Studio debugging and checking the log files these methods are never hit.

    public void fileuploadError(object sender, AsyncFileUploadEventArgs e)
    {
        logger.Debug("START method fileuploadError()");
        logger.Debug("END method fileuploadError()");
    }
    public void fileuploadClick(object sender, AsyncFileUploadEventArgs e)
    {
        logger.Debug("START method fileuploadClick()");            
        logger.Debug("END method fileuploadClick()");
    }

Other Answers have suggested that there is a problem with the control's visible setting being toggled between true/false but when the page is loaded directly by the url or navigating using be next and back buttons in the application, the control's visibility is never changed.

Though this did cause me to consider that as the control is not on the page's aspx code but is loaded serverside there could be an issue somewhere there. I had a problem with the next and back buttons events not triggering because of this and had to end up actually adding the code to the updatepanel for those controls to make the event trigger, but this is not an option for the question control as it changes from page to page.

Final bit of information to hopefully resolve a solution, the control does appear on the page, I can click on it and browse to a file but when I have selected the file it seems to call Page_Load and nothing else and the following 2 popups appear

 Server Response Error: 'Unknown Server Error'
 Do You want to see the response page?

and then

 Unhandled Exception: Server Response Error: 'Unknown Server Error'

This occurs in all browsers tested FF 8, Chrome 15.0, and IE 9

In firebug in Firefox I also get the following javaScript Error which could be related

 Index or size is negative or greater than the allowed amount
 [Break On This Error] Type.registerNamespace("Sys.Extended.U...FileUploadEventArgs",Sys.EventArgs); 

Any help would be appreciated.

EDIT 13/12/2011 I am using the AjaxControlToolkit version 4.1.5 downloaded today as the latest version and the problem still persists.


Solution

  • Problem Solved

    What I didn't realise was that none of my dynamically created fields were populated when a partial page post-back occurred. After having a look at this:

    I discovered that the controls need to be reinitialized before page load i.e. in the Page_Init, I changed the code slightly so that in the _displaySingleQuestion() method I told the session what the Question ID was and then called the method in Page_Init so the controls for the current question were on the page to be queried by the save method.

        public void Page_Init(object sender, EventArgs e)
        {
            logger.Debug("Page_Init START");
            if (!Page.IsPostBack) { Session["qid"] = 0; }
            int qid = Convert.ToInt32(Session["qid"]);
            if (qid > 0)
            {
                _displaySingleQuestion(_formObject, qid);
            }
            logger.Debug("Page_Init END");
        }
    

    This also meant that the AsyncFileUpload needed to be re-initialized before the page could continue, with this done my logging method is now recording that the fileuploadClick() event is being successfully called.

    Note, I added the line

     if (!Page.IsPostBack) { Session["qid"] = 0; }
    

    So that it would only try and get the values on a partial page postback and not a full page, such as when the page is first loaded.