I have very simple website (http://mysite.com), that contains one page, that page generates random datetime value and writes it to lable, code of that page is:
<form id="form1" runat="server">
<div>
<asp:Label ID="lblGeneratedDateTime" runat="server"></asp:Label>
<br />
<asp:DropDownList ID="ddlGenerateDateTime" runat="server" AutoPostBack="true"
onselectedindexchanged="ddlGenerateDateTime_SelectedIndexChanged">
<asp:ListItem Selected="True" Value="0">Today</asp:ListItem>
<asp:ListItem Value="1">-1 day</asp:ListItem>
<asp:ListItem Value="2">-2 days</asp:ListItem>
</asp:DropDownList>
</div>
</form>
and C# code:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
lblGeneratedDateTime.Text = GenerateDateTime(0).ToString();
}
}
protected void ddlGenerateDateTime_SelectedIndexChanged(object sender, EventArgs e)
{
int value = Convert.ToInt32(ddlGenerateDateTime.SelectedValue);
lblGeneratedDateTime.Text = GenerateDateTime(value).ToString();
}
Random random = new Random();
private DateTime GenerateDateTime(int minusDays)
{
DateTime date = DateTime.Now.AddDays(-minusDays);
return new DateTime(date.Year, date.Month, date.Day,
random.Next(0, 23), random.Next(0, 59), random.Next(0, 59));
}
}
Now, from WinForm App I need READ generated time on the page, so for default value I do:
string url = "http://mysite.com";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
string page = streamReader.ReadToEnd();
int start = str.IndexOf("lblGeneratedDateTime\">") + 22;
int end = str.LastIndexOf("</span>");
string generatedDateTime = str.Substring(start, end - start);
return generatedDateTime;
How can I read generated values (page content) for -1 and -2 days which needs do postback of DropDownList. Or it's impossible?
Thanks for any reply!
Added. Code of the site I can't change!
You can't do this like that... you download the html response as a string, so it's impossible to interact with the page and simulate a dropdown change..
You can try using WebClient and submit the form page with different value for you dropdown.. this will generate different responses that you can parse with your code above.
It needs to use WebBrowser instead.
WebBrowser wb = new WebBrowser();
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
string url = "http://mysite.com";
wb.Navigate(url);
HtmlElement item = wb.Document.GetElementById("ddlGenerateDateTime");
then
item.SetAttribute("value", "1");
item.InvokeMember("onchange");
item.SetAttribute("value", "2");
item.InvokeMember("onchange");
in that case it's possible to send postback to page.
Related
I am new to concept of web app with dynamic content.
I am creating simple app that take information (steps for a test) from database and adds rows to table (every row is containing, two labels, two radio buttons and text field).
It works like this:
1. I have a page with text box and button,
2. I put test ID to retrieve test steps, then click submit button
3. Based on number of steps I add a row to table for every step, so I have table that looks like this:
[Label.text="Step1"][RadioButtonPass][RadioButtonFail][Label.Text="Comment:"][TextBox]
[Label.text="Step2"][RadioButtonPass][RadioButtonFail][Label.Text="Comment:"][TextBox]
[Label.text="Step3"][RadioButtonPass][RadioButtonFail][Label.Text="Comment:"][TextBox]
etc.
When user press every radio button he can click submitResult button and data are send to db.
Page is genereting correctly but I am having trouble with dynamic content because when I hit submitResult button table is empty again (at this point submitResult button do nothing). I read about it and I think I need to store table into View State. How can I do it?
I tried to save table to
ViewState[table.ID] = table;
at the end of PopulateTable method and then restore it in
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
if (ViewState[TableForMethods.ID] != null)
{
TableForMethods = (Table)ViewState[TableForMethods.ID];
}
}
}
but that doesn't work.
My code looks like this:
*.aspx
<body style="height: 510px">
<form id="form1" runat="server">
<p>
Put test case ID and submit
</p>
<asp:TextBox ID="TextBoxId" runat="server">1804673290</asp:TextBox>
<asp:Button ID="ButtonRetriveId" runat="server" OnClick="ButtonSubmitId_Click" Text="Submit" Width="81px" />
<p>
</p>
<p>
<asp:Label ID="LabelMethods" runat="server"></asp:Label>
</p>
<p>
<asp:Table ID="TableForMethods" runat="server">
</asp:Table>
</p>
<div style="text-align: right">
<asp:Button ID="ButtonSubmitResults" runat="server" Text="Submit result" OnClick="ButtonSubmitResults_Click" Visible="False" />
</div>
<div style="text-align: right; position: absolute; bottom: 0px">
<asp:Label ID="LabelStatus" runat="server"></asp:Label>
</div>
</form>
<script>
var trPassArray = $("tr input[id*='RadioButtonPass']").click(function () {
this.closest("tr").setAttribute("bgcolor", "yellowgreen");
console.log("zmien na green");
console.log(closest("tr"));
});
var trFailArray = $("tr input[id*='RadioButtonFail']").click(function() {
this.closest("tr").setAttribute("bgcolor", "orangered");
console.log("zmien na red");
console.log(this.closest("tr"));
});
console.log(trPassArray);
console.log(trFailArray);
</script>
</body>
*.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ButtonSubmitId_Click(object sender, EventArgs e)
{
this.PopulateTable(TableForMethods, value);
ButtonSubmitResults.Visible = true;
}
protected void ButtonSubmitResults_Click(object sender, EventArgs e)
{
}
private void PopulateTable(Table table, string value)
{
string[] sep = { "<br>" };
var words = value.Split(sep, StringSplitOptions.RemoveEmptyEntries);
for (int iterator = 1; iterator <= words.Count(); iterator++)
{
var tRow = new TableRow { ID = "Row" + iterator };
table.Rows.Add(tRow);
var tCell = new TableCell();
var myLabel = new Label
{
Text = words[iterator - 1],
ID = "Label " + iterator
};
var radiobuttonPass = new RadioButton
{
Text = "Pass ",
ID = "RadioButtonPass " + iterator,
GroupName = "passFailGroup" + iterator,
};
radiobuttonPass.CheckedChanged += passRadioButton_CheckedChanged;
var radiobuttonFail = new RadioButton
{
Text = "Fail ",
ID = "RadioButtonFail " + iterator,
GroupName = "passFailGroup" + iterator,
};
radiobuttonFail.CheckedChanged += failRadioButton_CheckedChanged;
var upPassFail = new UpdatePanel { UpdateMode = UpdatePanelUpdateMode.Conditional };
upPassFail.ContentTemplateContainer.Controls.Add(radiobuttonPass);
upPassFail.ContentTemplateContainer.Controls.Add(radiobuttonFail);
var passTrigger = new AsyncPostBackTrigger
{
ControlID = radiobuttonPass.ID,
EventName = "CheckedChanged"
};
upPassFail.Triggers.Add(passTrigger);
var failTrigger = new AsyncPostBackTrigger
{
ControlID = radiobuttonFail.ID,
EventName = "CheckedChanged"
};
upPassFail.Triggers.Add(failTrigger);
var labelComment = new Label
{
Text = " Comment:",
ID = "LabelComment " + iterator.ToString()
};
TextBox textBoxComment = new TextBox { ID = "TextBoxComment " + iterator.ToString() };
tCell.Controls.Add(myLabel);
tCell.Controls.Add(radiobuttonPass);
tCell.Controls.Add(radiobuttonFail);
tCell.Controls.Add(labelComment);
tCell.Controls.Add(textBoxComment);
tRow.Cells.Add(tCell);
}
}
What you're trying to do won't work. ViewState is used by the server application to store information between requests.
During the course of page load or a postback the server modifies the state of the page or its controls
When you post back, without some way to "remember" what was done, all of those changes would be lost. It would be like loading the page for the first time again.
ASP.NET solves this by writing details about the controls in a form field (ViewState.) That way every time there's postback you're sending data back to the server telling it what the state of the page and controls are, so it can recreate it.
You're making changes to the HTML on the client. At that point the page has been rendered, including ViewState. It only keeps track of the server's changes, not anything that happens on the client. So the server will never know that those changes happened.
There are a few ways to solve this (more than two, but these are the obvious ones.)
Whatever changes have to happen to modify that table, do it on the server. If the user interacts with something, do a postback to the server. The server modifies the table, and assuming that ViewState is enabled for the table, those changes are already written to ViewState and persisted.
Avoid postbacks. If there aren't server controls then after the page loads it behaves just like a normal HTML page, and you can do whatever you want on the client.
This gets a little messy: store client-side changes on the client. When you update the table on the client then you could store it in localStorage. When the page refreshes you could then have a client script that checks localStorage and restores whatever client-side stuff you stored there. Think of it as just like ViewState, but the opposite. ViewState stores server-side data between roundtrips. localStorage stores client-side data between roundtrips. The catch is that maybe on some postback you'll completely change the table (like new data, something else) and you'll have to have a way to distinguish that so that in that scenario you don't refresh it from localStorage.
Mixing WebForms with client-side code can be a little frustrating. We start learning about all of these neat client-side tools, but they don't always play well with the behavior of WebForms. Client-side code wants to change things on the page. WebForms wants to refresh the whole page.
Personally I would go with option one or two if possible vs trying to cross-breed the behavior of the two.
I'm trying to make my first ASP.NET web site and am unable to get searching and paging to work in ASP.NET Web Forms without using an invisible button. I can't use my search button's click event because it needs to reset my page to 0 when clicked, so it only has a client-click event. I have to make it call a JavaScript function, which calls the invisible button's click event handler after doing so. The only way I can figure out around it is to make the page post back to itself and pass the index in from the bottom paging table. Hopefully, someone here might have some suggestions for an easier way to do it. Thanks in advance for any suggestions. If it wasn't for paging, it would be one line of code inside my button click event handler.
Here is the relevant markup for my page.
<script language="javascript">
function page(index)
{
document.getElementById('PageIndex').value = index;
document.getElementById('btnInvisible').click();
}
</script>
<uc1:ucWidgetSearch runat="server" id="ctl" />
<p id="pHTML" runat="server"/>
<asp:Button ID="btnInvisible" runat="server" BackColor="White"
BorderStyle="None" BorderWidth="0px" OnClick="btnInvisible_Click" />
<asp:HiddenField ID="PageIndex" runat="server" /
Here is the markup for the UserControl on the page.
<label>Last Name:</label>
<asp:TextBox ID="txtLastName" runat="server" MaxLength="50" Enabled="false"></asp:TextBox>
<asp:Button ID="btnSearch" runat="server" Text="Search" OnClientClick="page('0')" />
Here is the C# code behind for the .aspx page. The .aspx page uses no using statements.
namespace Widgets.WebUI
{ public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, System.EventArgs e)
{ ScreenHelper.LoadScreen(ctl.Search(), pHTML, PageIndex);}
protected void btnInvisible_Click(object sender, System.EventArgs e)
{ }
}
}
Here is the code behind for the UserControl. It also uses no using statements.
public partial class ucWidgetSearch : System.Web.UI.UserControl
{
internal Widgets.BLL.WidgetSearch Search()
{
if (!txtLastName.Enabled)
{
txtLastName.Enabled = true;
txtLastName.Focus();
return null;
}
return new Widgets.BLL.WidgetSearch(txtLastName.Text);
}
}
Finally, there is a ScreenHelper class that calls into the BLL layer, which calls into the DAL layer and constructs an HTML document and passes it into the p element on the main page.
internal class ScreenHelper
{
internal static void LoadScreen(WidgetSearch search,
System.Web.UI.HtmlControls.HtmlGenericControl p, HiddenField page)
{
if (search != null)
{
try
{
p.InnerHtml = WidgetsLogic.GetHTMLTable(search.LastName, int.Parse(page.Value), 20);
}
catch (System.Exception ex)
{
p.InnerHtml = "<label style=\"color: #FF0000\">Error loading screen: " + ex.Message + "</label>";
}
}
}
}
namespace Widgets.BLL
{
public class WidgetsLogic
{
public static string GetHTMLTable(string name, int pageIndex, int? pageSize)
{
StringBuilder strBuilder = new StringBuilder("<table border=\"1\">");
List<Widget> list = WidgetsDataAccess.GetByName(name);
int minDex = 0, maxDex = list.Count;
if (pageSize == null)
{
pageIndex = 0;
}
else
{
pageIndex = HTMLHelper.GetPageIndex(pageIndex, pageSize.Value, list.Count);
minDex = pageIndex * pageSize.Value;
maxDex = minDex + pageSize.Value;
if (maxDex > list.Count)
maxDex = list.Count;
}
for (int i = minDex; i < maxDex; i++)
{
strBuilder.Append("<tr");
// Set Light Gray Color for alterating rows in table
if (i%2 != 0)
strBuilder.Append(" style=\"background-color: #EBEBEB\"");
strBuilder.Append("><td>" + list[i].ID.ToString() + "</td>");
strBuilder.Append("<td>" + list[i].Name + "</td></tr>");
}
strBuilder.Append("</table>");
// Add Paging if appropriate
if (pageSize != null && pageSize.Value < list.Count)
{
strBuilder.Append(HTMLHelper.GetPagingFooter(pageIndex, pageSize.Value,
list.Count, "javascript:page('#pageIndex')"));
}
string str = strBuilder.ToString();
return str;
}
}
you should never try to do paging manually. Rather use GridView and an ObjectDataSource
to bind data to your page. This way ASP.NET handles the pageIndex exc via viewstate and the ObjectDatasource handles paging for you.Check this link for a good example of how to do just that.
Use ClientID to refer to the actual ID of an HTML control
document.getElementById('<%= PageIndex.ClientID %>').value = index;
i need my program to open this image in a new tab when it's genenrate it.
here is the genreate code (C#) :
imageFileName = string.Format
(_canvasFolderName + "/canvas_finalsprite_{0}.png", _sequenceNbr);
string imageServerFileName =
HttpContext.Current.Server.MapPath(imageFileName);
bitmap.Save(imageServerFileName, ImageFormat.Png);
the callingt to generate :
var imgSprite = (Image) (e.Item.FindControl("imgSprite"));
imgSprite.ImageUrl = _canvas.SpriteToImage(stats.FinalSprite);
and this is the aspx code:
<asp:Image ID="imgSprite" runat="server" />
i need when it will get to the line imgSprite.ImageUrl = _canvas.SpriteToImage(stats.FinalSprite); to create the image in new tab
also it will be much better if it will be in print mode for this picutre in the new tab.
Make your image an ASP image button
<asp:ImageButton D="imgSprite" runat="server" ibnCommand="ibtmImage_Command" />
and create a method to do something like
protected void ibtmImage_Command(object sender, CommandEventArgs e)
{
string strJS = ("window.open('ItemList.aspx?Id=" + e.CommandArgument.ToString() + "','_blank');");
Page.ClientScript.RegisterStartupScript(this.GetType(), "strJSAlert", strJS);
}
This can be a local file to your project as well
I'm trying to create text box dynamically. so I cal it through the AJAX function.
This is my code:
Ajax function
function ChangedAdults(noofAdults) {
alert(noofAdults.value);
$.ajax({
type: 'POST',
dataType: 'json',
url: "/FlightBooking.aspx/Adults",
data: "{noOfAdults:'" + noofAdults.value + "'}",
contentType: "application/json; charset=utf-8",
success: function (result) {
$("#AdultsList").html(result.d);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}
code behind
[WebMethod]
public static string Adults(int noOfAdults)
{
FlightBooking obj = new FlightBooking();
obj.CreateAdultsList(noOfAdults);
string test= "";
return test.ToString();
}
private void CreateAdultsList(int noOfAdults)
{
int n = noOfAdults;
for (int i = 0; i < n; i++)
{
TextBox MyTextBox = new TextBox();
MyTextBox.ID = "tb" + "" + i;
AdultsListPlaceholder.Controls.Add(MyTextBox); //error coming here
AdultsListPlaceholder.Controls.Add(new LiteralControl("<br />"));
}
}
But I receive an error:
Object reference not set to an instance of an object
What could cause this problem?
You can not dynamically add controls to a page using JQuery AJAX. Please get a good understanding of asp.net page lifecycle
In short this is how asp.net pages work.
Browswer sends request to server. i.e. http://localhost/test.aspx
Server creates a object for the page class. In this case the class is Test
The object renders the page. That means it converts the Controls of test.aspx to HTML which browsers can understand.
Server sends the rendered HTML back to Browser and destroys the object.
Browser displays the page.
So the server creates a new object every time it receives a page request.
However when a call to WebMethods is made using AJAX, no page object is created. This is why Webmethods have to be static.
I can see you are trying to create a object yourself and add the dynamic controls to that object. But this object is not related to the content displayed in the browser. So, adding controls to this object won't change anything that's displayed in the browser. For that to happen you have to post the whole page back. And if you return the rendered output of the object you created with Response.Write, that will return the HTML version of the whole page. Which is basically same as a PostBack
However, you can achieve AJAX based dynamic control rendering using UpdatePanel. Below is one way to do it
ASPX page
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<asp:Button ID="btnCreate" runat="server" Text="Create" OnClick="btnCreate_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="btnRead" runat="server" Text="Read" OnClick="btnRead_Click" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</form>
Code Behind
protected int NumberOfControls
{
get { return Convert.ToInt32(Session["noCon"]); }
set { Session["noCon"] = value.ToString(); }
}
private void Page_Init(object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
//Initiate the counter of dynamically added controls
this.NumberOfControls = 0;
else
//Controls must be repeatedly be created on postback
this.createControls();
}
private void Page_Load(object sender, System.EventArgs e)
{
}
protected void btnCreate_Click(object sender, EventArgs e)
{
TextBox tbx = new TextBox();
tbx.ID = "txtData"+NumberOfControls;
NumberOfControls++;
PlaceHolder1.Controls.Add(tbx);
}
protected void btnRead_Click(object sender, EventArgs e)
{
int count = this.NumberOfControls;
for (int i = 0; i < count; i++)
{
TextBox tx = (TextBox)PlaceHolder1.FindControl("txtData" + i.ToString());
//Add the Controls to the container of your choice
Label1.Text += tx.Text + ",";
}
}
private void createControls()
{
int count = this.NumberOfControls;
for (int i = 0; i < count; i++)
{
TextBox tx = new TextBox();
tx.ID = "txtData" + i.ToString();
//Add the Controls to the container of your choice
PlaceHolder1.Controls.Add(tx);
}
}
Hope this helps.
You're mixing your paradigms. What would you expect this code to do? You can render controls in response to an AJAX call, but you must then manually insert the processed HTML into the DOM.
Call server using AJAX
Instantiate a dummy page container
Render server control
Return markup
Insert into DOM
Or, you can add new controls in response to a server event via a full postback or an async postback (e.g. an UpdatePanel).
In asp.net you can not create server control from jQuery or java-script.
Though you can call web-method from jQuery but you can't add any control from web method.
More details
Add new ASP.NEt server controls with jQuery?
One of the idea it to create textbox is to create html textbox
<input type="text" id="text1" ></input>
And post your value through jQuery ajax for manipulation.
Edit 1
Other way is to create all the controls at page load (If you know the maximum number)
Hide them initially
Show one by one on button click
And get the value on the server after postback.
Example:
add text to an asp.net textbox control with jQuery
AdultsListPlaceholder is null, you need to override its onload function to create children of this control.
e.g.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
CreateAdultsList(5);
}
Fairly straightforward. I'm just looking for users to be able to add a title to the file before uploading. (Yes, I encourage proper filenames, but that's not the point.)
<asp:TextBox runat="server" ID="txtDocumentTitle" />
<ajaxToolkit:AjaxFileUpload runat="server" ID="ajxUploadNDA" OnUploadComplete="ajxUpload_Complete" Width="400px" /><br />
protected void ajxUpload_Complete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e)
{
MyFile f = new MyFile();
f.DocumentType = e.ContentType;
f.FileBytes = e.GetContents();
f.FileName = e.FileName;
f.DocumentCategory = "Package Files";
f.FileUploaded = DateTime.Now;
f.DocumentTitle = txtDocumentTitle.Text;
f.Save();
DataBind();
}
However when setting a breakpoint, txtDocumentTitle.Text is always blank. I can't seem to force a full postback or find any other way to get the current value of that textbox. I can allow the user to edit those properties after the file is uploaded, but that is not the design I'd prefer for a few reasons. (It encourages leaving values at default.)
I've tried:
protected void Page_Init(object sender, EventArgs e)
{
ScriptManager.GetCurrent(Page).RegisterPostBackControl(ajxUploadNDA);
ScriptManager.GetCurrent(Page).SupportsPartialRendering = false;
ScriptManager.GetCurrent(Page).EnablePartialRendering = false;
}
and I've tried
<ajaxToolkit:AjaxFileUpload runat="server" ID="ajxUploadNDA" OnUploadComplete="ajxUpload_Complete" Width="400px" onchange="if (confirm('Upload ' + this.value + '?')) this.form.submit();" />
Any suggestions would be more than welcome.
I've sort of solved it by adding a button to "Set Document Title" which adds the value of the textbox to session. The ajxUpload_Complete function then uses this Session variable to set the title to that session value on upload.
It's sloppy for a couple reasons, but it's the best I could do.
On Page_Load:
if (!Page.IsPostBack && !ajxUploadNDA.IsInFileUploadPostBack)
{
Session.Remove("DefaultDocumentCategory");
lblDocumentCategory.Text = "Data Package Files";
Session.Remove("DefaultDocumentTitle");
lblDocumentTitle.Text = "Data Package File";
}
protected void btnChangeDocumentAttributes_Click(object sender, EventArgs e)
{
lblDocumentCategory.Text = cboDocumentCategory.SelectedValue;
lblDocumentTitle.Text = txtDocumentTitle.Text;
Session["DefaultDocumentCategory"] = lblDocumentCategory.Text;
Session["DefaultDocumentTitle"] = lblDocumentTitle.Text;
}
I also added a dummy button to the page to force a postback refreshing my gridview that shows all the files uploaded.
<asp:Button ID="btnForcePostBack" runat="server" Text="" Style="background-color: Transparent; color: inherit; border-style: none;" />
protected void ajxUpload_Complete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e)
{
MyFile f = new MyFile();
f.DocumentType = e.ContentType;
f.FileBytes = e.GetContents();
f.FileName = e.FileName;
f.FileUploaded = DateTime.Now;
if (Session["DefaultDocumentCategory"] == null || Session["DefaultDocumentCategory"].ToString() == string.Empty) f.DocumentCategory = "Data Package Files";
else f.DocumentCategory = Session["DefaultDocumentCategory"].ToString();
if (Session["DefaultDocumentTitle"] == null || Session["DefaultDocumentTitle"].ToString() == string.Empty) f.DocumentTitle = "Data Package File";
else f.DocumentTitle = Session["DefaultDocumentTitle"].ToString();
f.Save();
ajxUploadNDA.Page.ClientScript.RegisterStartupScript(this.GetType(), "RefreshParent", "<script type='text/javascript'>var btn = window.parent.document.getElementById('btnForcePostBack');if (btn) btn.click();</script>");
}
I couldn't get any of these other answers to work. I ended up putting the textbox on an ajax update panel. Then I created an event for the textbox OnTextboxChanged that stored the value in the session. Then I could grab the value in the UploadComplete right from the session.
When using ajax upload, you can only save right away, then second step would be to have separate call to get file from saved location and operate on it. I was having same issue with multiple asynchronous upload using Uploadify and Uploadifive. My first step when uploading multiple files is to save to temp location, then have second call to retrieve it, resize it and save it to cloud (Azure Storage). Its impossible to put a break point, since the threads are all over the place. Its a strange behavior, specially when uploading a single file, but that's the best solution to first save then retrieve using separate call.
The problem is that AjaxFleUpload control use hidden frame for submitting file content. You may use script below to pass textbox value to server:
Sys.Application.add_load(applicationLoadHandler);
function applicationLoadHandler() {
var originalCreateForm = Sys.Extended.UI.AjaxFileUpload.prototype._createVForm;
Sys.Extended.UI.AjaxFileUpload.prototype._createVForm = function () {
originalCreateForm.call(this);
var textBox = document.createElement("INPUT");
textBox.setAttribute("type", "text");
textBox.setAttribute("name", "<%= txtDocumentTitle.UniqueID %>");
textBox.setAttribute("value", document.getElementById("<%= txtDocumentTitle.ClientID %>").value);
this._vForm.appendChild(textBox);
}
}
On server you can get user input from Request.Form collection:
var title = Request.Form[txtDocumentTitle.UniqueID];