2013-12-17 104 views
0

我正在構建一個站點,我必須使用文件上傳控件來附加支持日誌/郵件等......我覺得將文件保存到數據庫中將是更好的選擇。從SQL Server數據庫檢索文件

我使用下面的代碼來上傳文件。但是,我無法測試它,因爲我不知道如何從數據庫中檢索文件。有人可以幫助我嗎?

文件類型可以是任何東西。

代碼:

FileUrl = "C:\\Attachments\\"+Path.GetFileName(UploadCtrl.NavigateUrl); 
FileStream fs = new FileStream(FileUrl, FileMode.Open, FileAccess.Read); 
BinaryReader br = new BinaryReader(fs); 
long numBytes = new FileInfo(FileUrl).Length; 
buff = br.ReadBytes(Convert.ToInt32(numBytes)); 
SqlConnection conn = new SqlConnection(SQLSrc.ConnectionString); 
conn.Open(); 
SqlCommand command = conn.CreateCommand(); 
string InsertQueryText = "insert into Attachments values ('" + Path.GetFileName(FileUrl) + "','" + MIME(Path.GetExtension(Att_Overview_Link.NavigateUrl)) + "','" + buff + "');"; 
command.CommandText = InsertQueryText; 
command.ExecuteNonQuery(); 

這裏,MIME是用戶定義的函數獲取指定的文件類型的MIME值。

前端:C#ASP.NET和SQL Server作爲後端

+0

你的代碼是容易[SQL注入](HTTP:// WWW。 troyhunt.com/2013/07/everything-you-wanted-to-know-about-sql.html)。改用參數化查詢。 –

回答

0

如果您使用的是SQL Server 2008或更近,你可以使用FILESTREAM存儲爲VARBINARY(最大值)數據類型。 This MSDN article包含一些C#示例代碼,可以完成您要做的事情。它還顯示瞭如何創建用於存儲文件的表格。

2

開始通過固定代碼刪除SQL Injection vulnerability

FileUrl = "C:\\Attachments\\" + Path.GetFileName(UploadCtrl.NavigateUrl); 

using (SqlConnection conn = new SqlConnection(SQLSrc.ConnectionString)) 
using (SqlCommand command = conn.CreateCommand()) 
{ 
    command.CommandText = "insert into Attachments values (@FileName, @MimeType, @FileBytes)"; 
    command.Parameters.AddWithValue("@FileName", Path.GetFileName(FileUrl)); 
    command.Parameters.AddWithValue("@MimeType", MIME(Path.GetExtension(Att_Overview_Link.NavigateUrl))); 
    command.Parameters.AddWithValue("@FileBytes", File.ReadAllBytes(FileUrl)); 

    conn.Open(); 
    command.ExecuteNonQuery(); 
} 

注:我不知道你的UploadCtrl是什麼,但大多數的文件上傳控件,得到作爲Stream直接訪問上傳的文件,而不是服務器上的文件名。根據特定控件的工作方式,您可能需要更改讀取上傳文件的方式。

要恢復的文件,你會選擇相關的名稱,MIME類型和字節,並將其寫入響應:

using (SqlConnection conn = new SqlConnection(SQLSrc.ConnectionString)) 
using (SqlCommand command = conn.CreateCommand()) 
{ 
    command.CommandText = "SELECT FileName, MimeType, FileBytes FROM Attachments WHERE PK = @PK"; 
    command.Parameters.AddWithValue("@PK", Request.QueryString["pk"]); 

    conn.Open(); 
    using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection)) 
    { 
     if (reader.Read()) 
     { 
     string name = reader.GetString(reader.GetOrdinal("FileName")); 
     Response.AppendHeader("Content-Disposition", "attachment; filename=" + name); 
     Response.ContentType = reader.GetString(reader.GetOrdinal("MimeType")); 

     int startIndex = 0; 
     byte[] buffer = new byte[4096]; 
     int fieldIndex = reader.GetOrdinal("FileBytes"); 
     int bytesRead = (int)reader.GetBytes(fieldIndex, startIndex, buffer, 0, buffer.Length); 
     while (bytesRead != 0) 
     { 
      Response.OutputStream.Write(buffer, 0, bytesRead); 
      Response.Flush(); 

      startIndex += bytesRead; 
      bytesRead = (int)reader.GetBytes(fieldIndex, startIndex, buffer, 0, buffer.Length); 
     } 
     } 
    } 
}