views:

667

answers:

1

Technology: SharePoint/MOSS 2007 -- IDE: Visual Studio 2008 -- Language: C#

I have created a SharePoint/MOSS 2007 web part that displays a list of log files. The log files are rendered on screen as LinkButtons. The LinkButtons are within a DataTable that is set as the data source of a SPGridView and bound to it. This SPGridView object is then added to the 'Controls' within the overridden "CreateChildControls()" method of the web part.

I am utilising the following "DownloadAssistant" helper class to display a specified file. It's "DownloadFile" method is called from the '.Click' event of each LinkButton.

using System;
using System.Web;

/// <summary>
/// A class that helps to build download buttons/links on the fly
/// </summary>
static public class DownloadAssistant
{
    static public void DownloadFile(string filePath)
    {
        try
        {
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.AddHeader("Content-Disposition", string.Concat("attachment; filename=", filePath));
            HttpContext.Current.Response.ContentType = "application/octet-stream";
            HttpContext.Current.Response.WriteFile(filePath);
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

After one LinkButton is clicked on screen, I receive the download pop up window as expected and can go ahead and open the first log file. However after this first log file is opened, i.e. after the first LinkButton click event is triggered, I cannot trigger any other .Click event - it is as it I need to post back to the screen. When I click on any of the other LinkButtons nothing happens?

The Web Part code:

namespace LogRetrievalWebPart
{
    [Guid("fd243ec2-83e3-4bad-af5e-c5c16acbc6dd")]
    public class LogRetrievalWebPart : System.Web.UI.WebControls.WebParts.WebPart
    {
        // Member variables prefixed with "m_"
        private Label m_InfoLbl;
        private SPGridView m_GridView;
        private DataTable m_LogFileDataTable;
        private DropDownList m_DirectoryDropDown;


        private const String DROPDOWN_OPTION_DEFAULT = "---";
        private const String DROPDOWN_OPTION_TRACE_LOGS = "Trace Logs";
        private const String DROPDOWN_OPTION_BATCH_LOGS = "Batch Logs";
        private const String DROPDOWN_OPTION_OTHER_LOGS = "Other Logs";

        public LogRetrievalWebPart()
        {
            this.ExportMode = WebPartExportMode.All;
        }

        protected override void CreateChildControls()
        { 
            EnsureChildControls();

            base.CreateChildControls();

            m_InfoLbl = new Label();
            Label dropDownLbl = new Label();
            dropDownLbl.Text = " Please select a directory:  ";
            this.Controls.Add(dropDownLbl);


            m_DirectoryDropDown = new DropDownList();
            m_DirectoryDropDown.Items.Add(DROPDOWN_OPTION_DEFAULT);
            m_DirectoryDropDown.Items.Add(DROPDOWN_OPTION_TRACE_LOGS);
            m_DirectoryDropDown.Items.Add(DROPDOWN_OPTION_BATCH_LOGS);
            m_DirectoryDropDown.Items.Add(DROPDOWN_OPTION_OTHER_LOGS);
            m_DirectoryDropDown.TextChanged += new EventHandler(directoryDropdown_TextChanged);
            m_DirectoryDropDown.AutoPostBack = true;

            m_LogFileDataTable = new DataTable("LogFiles");
            AddColums();

            m_GridView = new SPGridView();
            m_GridView.AutoGenerateColumns = false;

            BoundField idField = new BoundField();
            idField.DataField = "ID";
            idField.HeaderText = "ID";
            m_GridView.Columns.Add(idField);

            TemplateField colName = new TemplateField();
            colName.HeaderText = "Log File Name";
            colName.SortExpression = "LogFileName";
            colName.ItemTemplate = new LinkTemplate("LogFileName", "Path");
            m_GridView.Columns.Add(colName);

            this.Controls.Add(m_DirectoryDropDown);
            this.Controls.Add(m_InfoLbl);
            this.Controls.Add(m_GridView);

            this.Load += new EventHandler(LogRetrievalWebPart_Load);
            this.PreRender += new EventHandler(LogRetrievalWebPart_PreRender);
        }

    void LogRetrievalWebPart_Load(object sender, EventArgs e)
    {
        EnsureChildControls();
    }

    protected void directoryDropdown_TextChanged(object sender, EventArgs e)
    {
        ViewState["LogRetrieval"] = null;
        String selectedDirectoryName = m_DirectoryDropDown.SelectedItem.Text;

        if (DROPDOWN_OPTION_TRACE_LOGS.Equals(selectedDirectoryName))
        {
            m_InfoLbl.Text = " *** TRACE Logs: *** ";
            GetLogFiles("LogFiles/TraceLogs");
        }
        else if (DROPDOWN_OPTION_BATCH_LOGS.Equals(selectedDirectoryName))
        {
            m_InfoLbl.Text = " *** BATCH Logs: *** ";
            GetLogFiles("PortalExecutables/Logs");
        }
        else if (DROPDOWN_OPTION_OTHER_LOGS.Equals(selectedDirectoryName))
        {
            m_InfoLbl.Text = " *** OTHER Logs: *** ";
            GetLogFiles("PortalExecutables/GMExecutables");
        }
        else
        {
            m_InfoLbl.Text = " *** No Logs to display for this selection!!! *** ";
        }

        ViewState["LogRetrieval"] = m_LogFileDataTable;
        m_GridView.DataSource = m_LogFileDataTable;
        m_GridView.DataBind();
    }

    private void GetLogFiles(string aSelectedDirectory)
    {
        string directoryPath = HttpContext.Current.Server.MapPath(ResolveUrl("/LogFiles/" + aSelectedDirectory));

        DirectoryInfo directory = new DirectoryInfo(directoryPath);
        FileInfo[] files = directory.GetFiles();

        int count = 1;
        foreach (FileInfo fileInfo in files)
        {
            string fullFileName = fileInfo.FullName;
            string fileName = fileInfo.ToString();

            AddRow(count, fileName, fullFileName);
            count++;
        }
    }

    private void AddRow(int id, string logFileName, string fullFileName)
    {
        DataRow newRow = m_LogFileDataTable.Rows.Add();
        newRow["ID"] = id;
        newRow["LogFileName"] = logFileName;
        newRow["Path"] = fullFileName;
    }

    private void AddColums()
    {
        DataColumn idCol = m_LogFileDataTable.Columns.Add("ID", typeof(Int32));
        idCol.Unique = true;

        m_LogFileDataTable.Columns.Add("LogFileName", typeof(String));
        m_LogFileDataTable.Columns.Add("Path", typeof(String));
    }

    public void LogRetrievalWebPart_PreRender(object sender, EventArgs e)
    {
        if (this.Page.IsPostBack)
        {
            if (ViewState["LogRetrieval"] != null)
            {
                m_LogFileDataTable = (DataTable)ViewState["LogRetrieval"];
                m_GridView.DataSource = m_LogFileDataTable;
                m_GridView.DataBind();
            }
        }
    }

    public class LinkTemplate : ITemplate
    {
        string logFileName;
        string logFilePath;

        public LinkTemplate(string fieldName, string path)
        {
            logFileName = fieldName;
            logFilePath = path;
        }

        public void InstantiateIn(Control container)
        {
            LinkButton link = new LinkButton();
            container.Controls.Add(link);

            link.DataBinding += new EventHandler(link_DataBinding);
            link.Click += new EventHandler(link_Click);
        }

        private void link_DataBinding(Object sender, EventArgs e)
        {
            LinkButton link = (LinkButton)sender;
            DataRowView dataRow = (DataRowView)((SPGridViewRow)link.NamingContainer).DataItem;

            link.Text = dataRow[logFileName].ToString();
            link.CommandArgument = dataRow[logFilePath].ToString();
        }

        private void link_Click(object sender, EventArgs e)
        {
            LinkButton link = (LinkButton)sender;
            DownloadAssistant.DownloadFile(link.CommandArgument);
        }
    }
}
}
A: 

I found a solution. I had to:

  1. Set the button's client-side click event to: "exportRequested=true;"
  2. Register the some JavaScript: For exact details, refer to:

http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/55136e4e-e1f7-4a79-9b75-be09cd5594c2