user3727052
user3727052

Reputation: 33

Unable to cast object of type 'system.string' to type 'system.Byte[]' when trying to download a file from database

I am trying to download a file from database but its giving me an error called Unable to cast object of type 'System.String' to type 'System.Byte[]' on the line : Response.AddHeader("Content-Length", bytes.ToString());

Please tell me how can I cast string to byte in my case, thank you in advance.

I have a column named SaleFileName from which I want to download a file.

Aspx code:

 <asp:TemplateField HeaderText="RecieptName" SortExpression="RecieptName">
                                <ItemTemplate>
                                    <asp:LinkButton ID="LinkButton1" runat="server" CommandName="Download" CommandArgument='<%# Bind("SaleName") %>' Text='<%# Bind("SaleName") %>' ></asp:LinkButton>
                                </ItemTemplate>
                            </asp:TemplateField>

Code Behind File:

 protected void gridContributions_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "Download")
        {

            // make sure fileName  contains only file name like 'test.pdf'  
            string FileName = Convert.ToString(e.CommandArgument);

            // make sure filePath  contains file path like 'Uploads/Scheme/test.pdf' 

             string FilePath = e.CommandArgument.ToString();


            string connectionString = WebConfigurationManager.ConnectionStrings["ConnectionString2"].ConnectionString;
            // SqlConnection con = new SqlConnection(connectionString);

           // byte[] bytes;
            //string ContentType;

            using (SqlConnection con = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = new SqlCommand())
                {
                    cmd.CommandText = "selectSaleFileName from Contributions where SaleFileName = @SaleFileName";
                    cmd.Parameters.AddWithValue("@SaleFileName", FileName);
                    //d.CommandType = CommandType.StoredProcedure;
                    cmd.Connection = con;
                    con.Open();
                    using ( SqlDataReader sdr = cmd.ExecuteReader())

                    {
                        sdr.Read();

                       bytes = (byte[])sdr["SaleFileName"];
                       //byte data = System.Text.Encoding.Unicode.GetBytes(SaleFileName.ToString);



                    }
                    con.Close();

                }
            }
            Response.Clear();
            Response.Buffer = true;

            // Read the original file from disk
             FileStream myFileStream = new FileStream( FilePath  ,FileMode.Open);
            long FileSize = myFileStream.Length;
            byte[] Buffer = new byte[Convert.ToInt32(FileSize)];
            myFileStream.Read(Buffer, 0, Convert.ToInt32(FileSize));
            myFileStream.Close();




           // // Tell the browse stuff about the file
            Response.AddHeader("Content-Length", bytes.ToString());
           // Response.AddHeader("Content-Length", FileNam
                //Response.AddHeader("Content-Disposition", "inline; filename=" & fileName.Replace(" ", "_"));
            Response.AddHeader("Content-Disposition", "attachment; FileName=" + FileName + ";");
            Response.TransmitFile(FileName);
            Response.ContentType = "application/octet-stream";

            // Send the data to the browser
            Response.BinaryWrite(Buffer);
            Response.End();
        }
    }

Upvotes: 0

Views: 2206

Answers (1)

Wajdy Essam
Wajdy Essam

Reputation: 4340

You can't cast byte[] to string (unless its textual data and you should encode the data using any encoding like unicode, ASCII)

anyway, the problem in the Content-Length on http header, it should be the length of the file

so replace this line:

Response.AddHeader("Content-Length", bytes.ToString());

with this:

Response.AddHeader("Content-Length", FileSize.ToString());

if the file is stored databaase you need to get it as byte array, the following code will help you:

private byte[] ReadFileFromDatabase(string FileName) {
    string connectionString = WebConfigurationManager.ConnectionStrings["ConnectionString2"].ConnectionString;  
    byte[] bytes = null;

    using (SqlConnection con = new SqlConnection(connectionString))
    {
        using (SqlCommand cmd = new SqlCommand())
        {
            cmd.CommandText = "selectSaleFileName from Contributions where SaleFileName = @SaleFileName";
            cmd.Parameters.AddWithValue("@SaleFileName", FileName);
            cmd.Connection = con;
            con.Open();

            using ( SqlDataReader sdr = cmd.ExecuteReader())
            {
               if (sdr.Read() )
                  bytes = (byte[])sdr["SaleFileName"];
            }
            con.Close();
        }
    }

    return bytes;
}

protected void gridContributions_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "Download")
    {
        string FileName = Convert.ToString(e.CommandArgument);      
        byte[] bytes = ReadFileFromDatabase(FileName);

        Response.Clear()
        Response.ContentType = "application/octet-stream"
        Response.AddHeader("Content-Disposition", "attachment; FileName=" + FileName + ";");
        Response.BinaryWrite(bytes)
        Response.End()
    }
}

if your file is stored outside database:

public static void DownloadFile(string path, string contentType)
{
    FileInfo file = new FileInfo(path);
    if (file.Exists)
    {                
        Response.Clear();
        Response.ClearHeaders();
        Response.ClearContent();

        Response.AddHeader("Content-Type", contentType);
        Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
        Response.AddHeader("Content-Length", file.Length.ToString());   

        Response.Flush();
        Response.TransmitFile(file.FullName);
        Response.End();
    }
}

call it as:

string fullPath = Server.MapPath(relativePath);
DownloadFile(fullPath , "application/octet-stream");

Upvotes: 1

Related Questions