C# 从SQL数据库读取BLOB对象时,文件已损坏
好的,有人能帮忙吗 在SQL DB中读取BLOB对象时出现问题。文件已下载,但无法打开,因为文件已损坏。任何文档类型(pdf、docx、jpg等)都会出现错误 代码执行一个存储过程,该过程根据两个不同的参数获取二进制文件 代码如下: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
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)