C# 从SQL数据库读取BLOB对象时,文件已损坏

C# 从SQL数据库读取BLOB对象时,文件已损坏,c#,asp.net,webforms,C#,Asp.net,Webforms,好的,有人能帮忙吗 在SQL DB中读取BLOB对象时出现问题。文件已下载,但无法打开,因为文件已损坏。任何文档类型(pdf、docx、jpg等)都会出现错误 代码执行一个存储过程,该过程根据两个不同的参数获取二进制文件 代码如下: protected void Page_Load(object sender, EventArgs e) { // Request.QueryString["docid"].ToString(); //str

好的,有人能帮忙吗

在SQL DB中读取BLOB对象时出现问题。文件已下载,但无法打开,因为文件已损坏。任何文档类型(pdf、docx、jpg等)都会出现错误

代码执行一个存储过程,该过程根据两个不同的参数获取二进制文件

代码如下:

        protected void Page_Load(object sender, EventArgs e)
    {
        // Request.QueryString["docid"].ToString(); 
        //string DocumentID = Request.QueryString["DocumentID"].ToString();
        string DocumentID = "9163736c-8064-11e8-ab16-2c44fd826130";
        string SessionId = "91494483-8064-11e8-ab16-2c44fd826130";
        //Connection and Parameters
        SqlParameter param1 = null;
        SqlParameter param2 = null;
        SqlConnection conn = new SqlConnection(
           ConfigurationManager.ConnectionStrings["ProcessManagerConnectionString"].ToString());
        SqlCommand cmd = new SqlCommand("sp_getdoc", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        param1 = new SqlParameter("@DocumentID", SqlDbType.NVarChar, 100);
        param2 = new SqlParameter("@SessionId", SqlDbType.NVarChar, 100);
        param1.Direction = ParameterDirection.Input;
        param2.Direction = ParameterDirection.Input;
        param1.Value = DocumentID;
        param2.Value = SessionId;
        cmd.Parameters.Add(param1);
        cmd.Parameters.Add(param2);
        //Open connection and fetch the data with reader
        conn.Open();
        SqlDataReader reader =
          cmd.ExecuteReader(CommandBehavior.CloseConnection);
        if (reader.HasRows)
        {
            reader.Read();
            //
            string doctype = reader["Extension"].ToString();
            string docname = reader["Docname"].ToString();
            //
            Response.Buffer = false;
            Response.ClearHeaders();
            Response.ContentType = doctype;
            Response.AddHeader("Content-Disposition",
                     "attachment; filename=" + docname);
            //
            //Code for streaming the object while writing
            const int ChunkSize = 1024;
            byte[] buffer = new byte[ChunkSize];
            byte[] binary = (reader["Data"]) as byte[];
            MemoryStream ms = new MemoryStream(binary);
            int SizeToWrite = ChunkSize;

            for (int i = 0; i < binary.GetUpperBound(0) - 1; i = i + ChunkSize)
            {
                if (!Response.IsClientConnected) return;
                if (i + ChunkSize >= binary.Length)
                    SizeToWrite = binary.Length - i;
                byte[] chunk = new byte[SizeToWrite];
                ms.Read(chunk, 0, SizeToWrite);
                Response.BinaryWrite(chunk);
                Response.Flush();
            }
            Response.Close();

        }
受保护的无效页面加载(对象发送方,事件参数e)
{
//Request.QueryString[“docid”].ToString();
//string DocumentID=Request.QueryString[“DocumentID”].ToString();
字符串DocumentID=“9163736c-8064-11e8-ab16-2c44fd826130”;
字符串SessionId=“91494483-8064-11e8-ab16-2c44fd826130”;
//连接和参数
SqlParameter param1=null;
SqlParameter param2=null;
SqlConnection conn=新的SqlConnection(
ConfigurationManager.ConnectionString[“ProcessManagerConnectionString”].ToString());
SqlCommand cmd=新的SqlCommand(“sp_getdoc”,conn);
cmd.CommandType=CommandType.storedProcess;
param1=新的SqlParameter(“@DocumentID”,SqlDbType.NVarChar,100);
param2=新的SqlParameter(“@SessionId”,SqlDbType.NVarChar,100);
param1.Direction=ParameterDirection.Input;
param2.Direction=ParameterDirection.Input;
param1.Value=DocumentID;
param2.Value=SessionId;
cmd.Parameters.Add(param1);
cmd.Parameters.Add(param2);
//打开连接并使用读卡器获取数据
conn.Open();
SqlDataReader阅读器=
cmd.ExecuteReader(CommandBehavior.CloseConnection);
if(reader.HasRows)
{
reader.Read();
//
字符串doctype=reader[“Extension”].ToString();
字符串docname=reader[“docname”].ToString();
//
Response.Buffer=false;
Response.ClearHeaders();
Response.ContentType=doctype;
Response.AddHeader(“内容处置”,
“附件;文件名=”+docname);
//
//用于在写入时流式处理对象的代码
常量int ChunkSize=1024;
字节[]缓冲区=新字节[ChunkSize];
字节[]二进制=(读取器[“数据”])作为字节[];
MemoryStream ms=新的MemoryStream(二进制);
int-SizeToWrite=ChunkSize;
for(inti=0;i=binary.Length)
SizeToWrite=binary.Length-i;
byte[]chunk=新字节[SizeToWrite];
ms.Read(chunk,0,SizeToWrite);
二进制写入(块);
Response.Flush();
}
Response.Close();
}

此处无需进行任何分块。您已经将二进制数据加载到内存中。只需调用一次:

Response.BinaryWrite(binary);
避免创建
MemoryStream
之类的东西。我感觉你的分块代码有缺陷

如果您希望在流式传输二进制数据时减少应用程序中的内存使用,则应考虑使用
CommandBehavior.SequentialAccess

最后,我更喜欢使用简单的
System.Web.IHttpHandler
(ASHX)而不是
System.Web.UI.Page
(ASPX)来处理这类事情

尝试创建名为HectorsHandler.ashx的文件,该文件包含以下内容:

<%@ WebHandler Language="C#" Class="HectorsApp.HectorsHandler" %>

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web;

namespace HectorsApp
{
    public class HectorsHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext ctxt)
        {
            // Request.QueryString["docid"].ToString(); 
            //string DocumentID = Request.QueryString["DocumentID"].ToString();
            string DocumentID = "9163736c-8064-11e8-ab16-2c44fd826130";
            string SessionId = "91494483-8064-11e8-ab16-2c44fd826130";
            //Connection and Parameters
            SqlParameter param1 = null;
            SqlParameter param2 = null;
            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ProcessManagerConnectionString"].ToString()))
            {
                SqlCommand cmd = new SqlCommand("sp_getdoc", conn);
                cmd.CommandType = CommandType.StoredProcedure;
                param1 = new SqlParameter("@DocumentID", SqlDbType.NVarChar, 100);
                param2 = new SqlParameter("@SessionId", SqlDbType.NVarChar, 100);
                param1.Direction = ParameterDirection.Input;
                param2.Direction = ParameterDirection.Input;
                param1.Value = DocumentID;
                param2.Value = SessionId;
                cmd.Parameters.Add(param1);
                cmd.Parameters.Add(param2);
                //Open connection and fetch the data with reader
                conn.Open();
                using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
                {
                    if (reader.Read())
                    {
                        //
                        string doctype = reader["Extension"].ToString();
                        string docname = reader["Docname"].ToString();
                        //
                        ctxt.Response.BufferOutput = false;
                        ctxt.Response.Buffer = false;
                        ctxt.Response.ContentType = doctype;
                        ctxt.Response.AddHeader("Content-Disposition", "attachment; filename=" + docname);

                        //Code for streaming the object while writing
                        byte[] buffer = new byte[8040];
                        long dataIndex = 0;
                        while (ctxt.Response.IsClientConnected)
                        {
                            long bytesRead = reader.GetBytes(reader.GetOrdinal("Data"), dataIndex, buffer, 0, buffer.Length);
                            if (bytesRead == 0)
                            {
                                break;
                            }
                            ctxt.Response.OutputStream.Write(buffer, 0, (int)bytesRead);
                            ctxt.Response.OutputStream.Flush();
                            dataIndex += bytesRead;
                        }
                    }
                }
            }
        }

        public bool IsReusable
        {
            get { return false; }
        }
    }
}

使用制度;
使用系统配置;
使用系统数据;
使用System.Data.SqlClient;
使用System.Web;
命名空间HectorApp
{
公共类HectorsHandler:IHttpHandler
{
public void ProcessRequest(HttpContext-ctxt)
{
//Request.QueryString[“docid”].ToString();
//string DocumentID=Request.QueryString[“DocumentID”].ToString();
字符串DocumentID=“9163736c-8064-11e8-ab16-2c44fd826130”;
字符串SessionId=“91494483-8064-11e8-ab16-2c44fd826130”;
//连接和参数
SqlParameter param1=null;
SqlParameter param2=null;
使用(SqlConnection conn=new SqlConnection(ConfigurationManager.ConnectionString[“ProcessManagerConnectionString”].ToString())
{
SqlCommand cmd=新的SqlCommand(“sp_getdoc”,conn);
cmd.CommandType=CommandType.storedProcess;
param1=新的SqlParameter(“@DocumentID”,SqlDbType.NVarChar,100);
param2=新的SqlParameter(“@SessionId”,SqlDbType.NVarChar,100);
param1.Direction=ParameterDirection.Input;
param2.Direction=ParameterDirection.Input;
param1.Value=DocumentID;
param2.Value=SessionId;
cmd.Parameters.Add(param1);
cmd.Parameters.Add(param2);
//打开连接并使用读卡器获取数据
conn.Open();
使用(SqlDataReader=cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
if(reader.Read())
{
//
字符串doctype=reader[“Extension”].ToString();
字符串docname=reader[“docname”].ToString();
//
ctxt.Response.BufferOutput=false;
ctxt.Response.Buffer=false;
ctxt.Response.ContentType=doctype;
ctxt.Response.AddHeader(“内容处置”、“附件;文件名=“+docname”);
//用于在写入时流式处理对象的代码
字节[]缓冲区=新字节[8040];
长数据索引=0;
while(ctxt.Response.IsClientConnected)