0

I have used the following code to download files from the server which works fine in development and QA server in every browser but when it goes to production there was an error. The error is System.IO.DirectoryNotFoundException the part of the path is not correct

Code used:

protected void lnkDownload_Click(object sender, eventArgs e)
{            
            LinkButton lnkbtn = sender as LinkButton;
            GridViewRow gvrow = lnkbtn.NamingContainer as GridViewRow;
            string filePath = ((HtmlInputHidden)gvFilesDetails.Rows[gvrow.RowIndex].FindControl("hdnFileLocation")).Value.ToString();


            Response.AddHeader("Content-Disposition", "attachment;filename=\"" + filePath + "\"");
            Response.TransmitFile(Server.MapPath("~/" + filePath));
            Response.End();
}

The issue seems to be odd and painful to debug as it only occurs in Production server. Please help me out.

Tapas Mahata
  • 343
  • 6
  • 22
  • 1
    How about adding some logging into your code to make it production-ready? – weismat May 22 '13 at 09:27
  • Does your web application have permission to write to that specific location on the production server? – chridam May 22 '13 at 09:32
  • @chridam yes, the web application have full permission given. – Tapas Mahata May 22 '13 at 09:41
  • @watraplion: filepath contains the full path of the file to be downloaded e.g. "Attachment\DownloadableFiles\ProjectOverview.pptx" – Tapas Mahata May 22 '13 at 09:55
  • what is the value you getting in -> Server.MapPath("~/" + filePath) ? check the full URL is proper. If proper type the full URL in browser & check whether is dowing ur pptx file or not?? – watraplion May 22 '13 at 09:58
  • check whether u getting URL similar like this "http:\\SomeURLHere\Attachment\DownloadableFiles\ProjectOverview.pptx". If you getting like this, type that URL in new browser window & press enter. – watraplion May 22 '13 at 10:01
  • @watraplion: I am getting the correct path in the error message as you mentioned but I could not check it by pasting it on the browser as it is a production environment but the path is fine. – Tapas Mahata May 22 '13 at 10:19
  • Is there any issue with Response.End() because the same code works fine for a different page where Response.End() not used? Confused !!! – Tapas Mahata May 22 '13 at 10:23
  • No your code is perfect. But here you do not use Server.MapPath(..), if you do so surely it will point to the application phtsical path. So i think here its pointing c:\inetpub\... like this. You should add a key in web.config that your URL path and append the filename at run time. are you getting me? – watraplion May 22 '13 at 10:30
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/30401/discussion-between-tapas-mahata-and-watraplion) – Tapas Mahata May 22 '13 at 10:36
  • One same issue found here http://stackoverflow.com/questions/1869440/problems-with-response-transmitfile-response-end-and-ie – Tapas Mahata May 22 '13 at 10:40

3 Answers3

0

Server.MapPath will get the physical path corresponding to a virtual path. Please cross check your Application server(Production).

This is a code which i'm using in production, works good for me, you can have a look at it.

   protected void imgDownload_click(object sender, ImageClickEventArgs e)
{
    ImageButton imgbtn = (ImageButton)sender;
    GridViewRow row = (GridViewRow)imgbtn.NamingContainer;
     string strHFFileDetails =((HiddenField )row.FindControl("HFFileID")) .Value.ToString();
    string[] strFileDetails = strHFFileDetails.Split('?');
    string FilePath = strFileDetails[1].ToString();
    string filename = gvFiles.Rows[row.RowIndex].Cells[0].Text.ToString();
    string path = @FilePath;
    System.IO.FileInfo file = new System.IO.FileInfo(path);
    if (file.Exists)
    {
        Response.Clear();
        Response.AppendHeader("Content-Disposition:", "attachment; filename=" + file.Name);
        Response.AppendHeader("Content-Length", file.Length.ToString());
        Response.ContentType = "application/octet-stream";
        Response.TransmitFile(file.FullName);
        Response.End();
    }

}
Vignesh Paramasivam
  • 2,360
  • 5
  • 26
  • 57
0

@Tapas Mahata Try this one,

Define your web URL in web.config,

<appSettings>
     <add key="FileURL" value="http:\\www.WebSiteName.com\"/>
<appSettings>

In aspx.cs,

protected void lnkDownload_Click(object sender, eventArgs e)
{
   LinkButton lnkbtn = sender as LinkButton;
        GridViewRow gvrow = lnkbtn.NamingContainer as GridViewRow;
        string filePath = ((HtmlInputHidden)gvFilesDetails.Rows[gvrow.RowIndex].FindControl("hdnFileLocation")).Value.ToString();

        string fileURL = ConfigurationManager.AppSettings["FileURL"].ToString();
        Response.AddHeader("Content-Disposition", "attachment;filename=\"" + filePath + "\"");
        Response.TransmitFile(fileURL+filePath);
        Response.End();
}
watraplion
  • 287
  • 4
  • 17
0

@Tapas Mahata Try this also,

aspx Page:

<asp:GridView ID="gv" OnRowDataBound="gv_RowDataBound" AutoGenerateColumns="False" runat="server">
     <Columns>
         <asp:HyperLinkField Target="_blank" DataNavigateUrlFields="URL" DataTextField="URL" HeaderText="Document Path" />
     </Columns>
</asp:GridView>

aspx.cs Page :

private string docPath = "";
protected void Page_Load(object sender, EventArgs e)
{
     docPath = ResolveClientUrl("~/Uploads/");
}

protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
    HyperLink FileHyperlink = null;
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
       FileHyperlink = (HyperLink)e.Row.Cells[0].Controls[0];
       string fileName = FileHyperlink.Text.Replace("'", "''");
       FileHyperlink.NavigateUrl = docPath + fileName;
    }
}
watraplion
  • 287
  • 4
  • 17