0

I am trying to change the text of a asp:textbox and collapse some ajaxToolkit:CollapsiblePanelExtenders within some ascx controls on my page as well as output a dynamically generated file. I have no problem collapsing the CollapsiblePanelExtenders and changing the text of the textbox from the codebehind or outputting a file. The problem arises when I want BOTH of these events to happen on the same postback. Unfortunately using Response.Write negates all of the other changes to the page.

Thanks in advance

Ben
  • 2,058
  • 9
  • 29
  • 39
  • Could you provide the code you are using to collapse the CollapsiblePanelExtenders? – ChessWhiz Aug 25 '10 at 18:59
  • What are you doing with the output of this file? Is the user downloading it? – Steve Danner Aug 25 '10 at 19:01
  • What type of content is in the dynamically generated file? Could you create a server side control and output its content there instead of using Response.Write? – Nate Pinchot Aug 25 '10 at 19:02
  • ChessWhiz: I have a method within my ascx controls to collapse the CollapsiblePanelExtenders. It functions using: collapsibleExtenderID.Collapsed = true; collapsibleExtenderID.ClientState = "true"; – Ben Aug 25 '10 at 19:32
  • Steve: This file being generated is being downloaded by users. It is a dynamically generated Excel file Nate: I need to provide the file for download. I don't think doing this from a user control will make a difference. – Ben Aug 25 '10 at 19:36
  • @Ben: Who said anything about a user control, I said server side control :) I thought you were perhaps trying to just output something to the screen. If you need to do update text on the screen and download a file, try out my answer below. – Nate Pinchot Aug 25 '10 at 19:54

1 Answers1

3

Here is a quick concept example of how you could update text on the screen and download a file at the same time through an AJAX postback with an UpdatePanel.

ASPX code:

<asp:UpdatePanel id="update1" runat="server">
  <ContentTemplate>
    <asp:TextBox id="textbox1" runat="server" /><br />
    <asp:Button id="button1" onclick="button1_Click" runat="server" />
  </ContentTemplate>
</asp:UpdatePanel>

C# code:

private string GenerateDownloadLink(string fileContent, string fileName) {
  // worker process will need write access to this folder
  string downloadFolder = "./download";

  TextWriter file = new StreamWriter(Server.MapPath(downloadFolder) + @"\" + fileName);
  file.WriteLine(fileContent);
  file.Close();

  return downloadFolder + "/" + fileName;
}

private void button1_Click(object sender, EventArgs e) {
  textbox1.Text = "the file download will begin shortly...";

  string fileContent = "here is the content for a new dynamically generated file";

  string fileUrl = GenerateDownloadLink(fileContent, "hello.txt");

  ScriptManager.RegisterStartupScript(this, this.GetType(), "StartDownload", "window.location = '" + fileUrl + "';", true);
}

Also check out this MSDN example.

I would also like to add that UpdatePanels will eat your soul and you should get rid of them in favor of something like calling a WebMethod via AJAX if at all possible :)

Nate Pinchot
  • 3,288
  • 24
  • 35
  • This will not work as I need to generate the file when the button is clicked based on values in various fields on the page. I can't just redirect them to the file via javascript because it doesn't exist until after the button is clicked. – Ben Aug 25 '10 at 20:06
  • @Ben: Generate the file in `button1_Click` based on the fields on the page, save what would be the URL to the file, and then use it in the `ScriptManager.RegisterStartupScript`. – Nate Pinchot Aug 25 '10 at 20:14
  • @Nate: Could you provide some example of how to do this? I currently am writing the file out from memory and it doesn't have a URL. – Ben Aug 25 '10 at 20:29
  • @Ben: The solution is actually pretty simple. Instead of pointing `fileUrl` to a physical file location, point it to an `.aspx` file that accepts a few query string parameters (the fields you are basing your output on) and write out the file from memory there. If you don't want to use query string parameters because the field data is sensitive, you could shove the field data into the `Session`, or send them via POST with jQuery - the former being the easier of the two ways to accomplish this. – Nate Pinchot Aug 25 '10 at 20:35
  • @Nate: This solution is 90% of what I want. Do you have any suggestions on how to delete the generated file after the user has downloaded it? – Ben Aug 27 '10 at 19:52
  • @Ben: You could make a cleanup task for later, via a scheduled task. A cleaner solution would be to do something like what I suggested in the last comment. Instead of pointing the `fileUrl` to a physical file location, point it to an `.aspx` or `.ashx` (HttpHandler) and write the file out from there. – Nate Pinchot Aug 29 '10 at 00:19
  • @Nate: The .ashx solution did the trick. However, I did have to use the javascript window.open({URL OF .ashx}) method where I added the script to the page rather than the window.location = {URL of .ashx file} as the latter solution gave me the same problems as I was having intially. (The data that was supposed to be hidden by the collapsiblepanelextenders was showing even though they were collapsed). Thanks for your help. – Ben Aug 31 '10 at 12:00
  • @Ben: Thanks for the insight I will keep that in mind if I ever need to implement something similar with UpdatePanels :) Glad to hear you were able to get it working how you needed! – Nate Pinchot Aug 31 '10 at 13:40