Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
175
Calling a Full Postback from Within an AJAX-Enabled WebDataGrid Contained in an UpdatePanel
posted

My recent struggles with adapting to the new WebDataGrid, AJAX, et al., compel me to share something I have learned which I think others will need.

The Scenario: 

I have two WebDataGrids contained in an UpdatePanel.  Selecting a row in the Parent grid populates the Child grid from a child collection member of the Master grid's datasource (A CSLA object).  I am enabling AJAX and using the update panel to improve the user experience.

The Challenge:

The rows in the Child table represent files that have been uploaded to the server.  The first column in the grid consists of cells that contain a WebImageButton.  Clicking on the button should trigger a browser download of the respective file.

However, certain HttpResponse methods are not supported during asynchronous postbacks, e.g., those coming from controls contained in an UpdatePanel (see http://msdn.microsoft.com/en-us/library/bb386454.aspx?ppud=4). 

The Solution:

Through Google, I stumbled upon:

http://justgeeks.blogspot.com/2011/06/how-to-download-file-from-inside.html

In that post, the proposed solution used:

ClientScriptManager.GetPostBackClientHyperlink

which does not seem to work when the calling control is embedded in a WebDataGrid in an UpdatePanel.  However, the the author also referenced the following .Net interfaces and methods:

IPostBackEventhandler [See: http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackeventhandler.aspx]

ClientScriptManager.GetPostBackEventReference(control, string) [See: http://msdn.microsoft.com/en-us/library/system.web.ui.clientscriptmanager.getpostbackeventreference.aspx AND http://msdn.microsoft.com/en-us/library/ms153108.aspx]

Using the above, I created a custom control implementing the IPostBackEventHandler interface, then on the Child grid's InitializeRow event, I found the button, instantiated the custom control and added it to a PlaceHolder, then added a client-side "onClick" attribute to the button that references the custom control's IPostBackEventHandler implementation.

See below:

The Code:

In ASP:

...

<body>

    <form id="mainForm" runat="server"">

       <asp:PlaceHolder ID="DownloadPlaceHolder" runat="server">
       </asp:PlaceHolder>

    </form>

    ...

</body>

...

 

The Custom Control In C#

using System;

using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;

namespace Cww.Web
{

    public class SynchDownloader : Control, IPostBackEventHandler
    {
        private Page thePage;

public SynchDownloader(Page page)
        {
             thePage = page;
        }

        public void RaisePostBackEvent(string path)
        {
            FileInfo fileInfo = new FileInfo(path);
            thePage.Response.ClearContent();
            thePage.Response.ClearHeaders();
            thePage.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileInfo.Name);
            thePage.Response.AddHeader("Content-Length", fileInfo.Length.ToString());
            thePage.Response.TransmitFile(path);
            thePage.Response.End();
        }
    }
}

 

The CodeBehind in C#:

 protected void ChildGrid_InitializeRow(object sender, Infragistics.Web.UI.GridControls.RowEventArgs e)

        {
            e.Row.EnsureTemplate();
            Infragistics.WebUI.WebDataInput.WebImageButton btn = e.Row.Items[0].FindControl("DownloadButton") as Infragistics.WebUI.WebDataInput.WebImageButton;
            if (btn != null)
            {
                MyFileClass theFile = (MyFileClass)(btn.Parent as Infragistics.Web.UI.TemplateContainer).DataItem;
                string docPath = theFile.Path;
                SynchDownloader downLoader = new SynchDownloader(Page);
                downLoader.ID = string.Format("{0}_downloader", btn.ID );
                DownloadPlaceHolder.Controls.Add(downLoader);
                btn.Attributes.Add("onClick", Page.ClientScript.GetPostBackEventReference(downLoader, docPath)); 
            }
        }

And Voila!

Hope this is helpful to someone else.  I certainly don't know what I'd do without forums like these.

  • 10240
    posted

    Hi sportfish1850

    This is an initial update to let you know that I am looking into your issue. I will have another update for you regarding this matter on or before Friday.

     

  • 25665
    Offline posted

    Hello sportfish1850,

    Thank you for sharing this information and your experience with getting a full postback to work with a WebDataGrid inside an update panel to download the file you need.

    Sincerely,
    Mike P.
    Developer Support Engineer
    Infragistics, Inc.
    www.infragistics.com