0

I am having some trouble downloading a file from the file path saved in my SQL Server database.

The file is saved in my database as \\server\Exec\C_Exec.pdf so now I am trying to download that file.

The code I have so far is:

Select the id of the file you want to download:

protected void ContactsGridViewExec_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName.Equals("ExecCommand"))
    {
        int rowIndex = int.Parse(e.CommandArgument.ToString());
        var val = this.ExecGridView.DataKeys[rowIndex]["id"];
        string strQuery = "SELECT filename, filecontent, datestamp FROM FileTable WHERE id=@id";

        SqlCommand cmd = new SqlCommand(strQuery);
        cmd.Parameters.Add("@id", SqlDbType.Int).Value = val;

        DataTable dt = GetData(cmd);

        if (dt != null)
        {
            download(dt);
        }
    }
}

Then download the file:

private void download (DataTable dt)
{
    Byte[] bytes = (Byte[])dt.Rows[0]["filecontent"];
    Response.Buffer = true;
    Response.Charset = "";
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.ContentType = dt.Rows[0]["filecontent"].ToString();
    Response.AddHeader("content-disposition", "attachment;filename=" + dt.Rows[0]["filename"].ToString());
    Response.BinaryWrite(bytes);
    Response.Flush(); 
    Response.End();
}

This code throws an exception

System.InvalidCastException: 'Unable to cast object of type 'System.String' to type 'System.Byte[]'.'

When I remove this line

Byte[] bytes = (Byte[])dt.Rows[0]["filecontent"];

and

Response.BinaryWrite(bytes);

It then downloads the file but there are no information or can't open the file (in this case a PDF).

BSMP
  • 4,596
  • 8
  • 33
  • 44
  • I am going to ask an X/Y question here first. Why are your file contents stored in a column? If you are using SQL server - which assuming you tagged asp.net/c#, is highly likely - then store files as file streams. – Tanveer Badar Feb 06 '20 at 06:13
  • file content is the path to the file? –  Feb 06 '20 at 06:15
  • Does this answer your question? [Download/Stream file from URL - asp.net](https://stackoverflow.com/questions/5596747/download-stream-file-from-url-asp-net) – Sats Feb 06 '20 at 06:25

1 Answers1

0

You can use the following piece of code:

MyFileStream = new FileStream(dt.Rows[0]["filecontent"].ToString() ,FileMode.Open);
FileSize = MyFileStream.Length;

byte[] buffer = new byte[(int)FileSize];

Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "Application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=" + dt.Rows[0]["filename"].ToString());
Response.BinaryWrite(buffer);
Response.Flush(); 
Response.End();

Your problem is that you can't magically turn a string value to a byte array. You need to tell the class which is responsible to represent a file stream where in the file system the file is and then let it make the conversion for you.

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
  • Hi Thanks, I am getting this error `cannot convert from object to string` at this line –  Feb 06 '20 at 06:57
  • `FileStream MyFileStream = new FileStream(dt.Rows[0]["filecontent"], FileMode.Open); long FileSize = MyFileStream.Length; byte[] buffer = new byte[(int)FileSize];` –  Feb 06 '20 at 06:57
  • Sorry added .ToString(), FileMode.Open. However now it downloads the file but still failing to open the pdf. (File size is correct but says the pdf is corrupted or damaged? –  Feb 06 '20 at 07:00
  • Try to also change the content type as the updated answer. – Athanasios Kataras Feb 06 '20 at 07:10
  • Hi Still no luck :-( –  Feb 06 '20 at 08:16