Search code examples
c#sql-serverdownloadfilestream

FileStream download pulls page HTML


I am trying to set up FileStream to work in my application. I am pretty sure that the issue I am having is not within my Upload code. If I view the properties of my test file, it shows being 46 bytes. When I watch the debug step through my download command, it grabs a filelength of 46 bytes.

On the very last step when the file is actually downloaded in the browser a bunch of data is added to the file, specifically the entire HTML of the page itself. I have NO idea why this is happening.

protected void gvFilestream_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "GetFile")
        {

            SqlConnection objSqlCon = new SqlConnection(CS);
            objSqlCon.Open();
            SqlTransaction objSqlTran = objSqlCon.BeginTransaction();

            SqlCommand objSqlCmd = new SqlCommand("FileGet", objSqlCon, objSqlTran);
            objSqlCmd.CommandType = CommandType.StoredProcedure;

            SqlParameter objSqlParam1 = new SqlParameter("@ID", SqlDbType.VarChar);
            objSqlParam1.Value = e.CommandArgument;

            objSqlCmd.Parameters.Add(objSqlParam1);
            string path = string.Empty;
            string fileType = string.Empty;

            using (SqlDataReader sdr = objSqlCmd.ExecuteReader())
            {
                while (sdr.Read())
                {
                    path = sdr[0].ToString();
                    fileType = sdr[1].ToString();
                }

            }

            objSqlCmd = new SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()", objSqlCon, objSqlTran);

            byte[] objContext = (byte[])objSqlCmd.ExecuteScalar();


            SqlFileStream objSqlFileStream = new SqlFileStream(path, objContext, FileAccess.Read);

            byte[] buffer = new byte[(int)objSqlFileStream.Length];
            objSqlFileStream.Read(buffer, 0, buffer.Length);
            objSqlFileStream.Close();

            objSqlTran.Commit();
            Response.AddHeader("Content-disposition", "attachment; filename=" + Path.GetFileName(path) + fileType);
            // Here you need to manage the download file stuff according to your need
            Response.ContentType = "application/octet-stream";

            Response.BinaryWrite(buffer);
        }
    }

This is my code behind method for downloading the file. And below is a snippet from the top of the text file that is downloaded. I didn't put the whole thing in because it seems pointless. The original document only contains "This document is a test document, for testing."

This document is a test document, for testing.
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
    View
</title>

I am using a guide I found on the Internet to set this FileStream stuff up, but it doesn't really explain what each part is doing so I don't know where my method is going wrong. It seems like it would be in the comment area where I need to tailor it to my needs.

Any suggestions?


Solution

  • Clear the response by invoking Response.Clear() before writing the binary content to the output.

    To prevent further writes to the output, you should stop request execution right after that:

    Response.Clear();
    Response.BinaryWrite(buffer);
    Response.End();