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.
https://stackoverflow.com/a/2918382/728841
<form id="form1" runat="server" enctype="multipart/form-data" method="post">
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.
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.