2012-01-24 6 views
4

SQL Serverデータベースのカラムタイプがimage(悪い以前のdbデザイナ)のPDFファイルデータがあります。私がする必要があるのは、バイナリデータをクライアントに読み込んで、自分のコンピュータに直接PD​​Fをダウンロードできるようにすることです。次のようにデータベースからのバイナリファイルを開くC#

はこれまでのところ、私のコードは次のとおりです。

SqlConnection con = new SqlConnection(); 
con.ConnectionString = "casIntranetConnectionString"; 

SqlCommand com = new SqlCommand("SELECT [File], [FileName] FROM [com].[catalog1] WHERE [FileName] = @filename"); 
com.Connection = con; 
com.Parameters.AddWithValue("filename", Request.QueryString["filename"]); 

con.Open(); 

SqlDataReader reader = com.ExecuteReader(); 

if (reader.Read()) 
{ 
    Response.Clear(); 
    Response.AddHeader("Content-Type", "application/pdf"); 
    Response.AddHeader("Content-Disposition", "inline; filename=" + Request.QueryString["filename"] + ".pdf"); 
} 

私はバイトを読み出すためにリーダーが必要するつもりだと仮定していますが、私は本当に私が何をすべきか分からないところです。助言がありますか?

ありがとうございます!

+3

何かをする前に、2012年にADO.NETでこれを手動で行う理由はありますか? – TimothyP

+2

@TimothyPは適切な選択肢を示唆していますか? – TJHeuvel

+0

エンティティフレームワークなどの技術を見てみることをお勧めしますが、私はあなたのプロジェクトに適しているかどうかについてはっきりと伝えていません。それはあなたが何に焦点を合わせることができますし、そうではありません。 – TimothyP

答えて

5

あなたはHttpResponseにBinaryWrite methodを使用することができますデータベースと応答への書き込み。これにより、将来的にメンテナンスの問題が発生します。固体の原理を説明しているhere for a useful blog postを参照してください。あなたのコードスニペットが考案された場合にはお詫びしますが、他の誰かがこの疑問を突きつけた場合には、「このようにしないでください」という免責事項を含めると思います!

1

は、私は、これは動作するはずと信じて:あなたがアクセスするための責任がある方法を持って、責任を分離を検討してください、余談として

var bytes = reader.GetSqlBytes(index); 
Response.BinaryWrite(bytes.Value); 

if(reader.Read()) 
{ 
    Byte[] pdfData = (byte[])reader.GetValue(0);; 
    Response.Buffer = true; 
    Response.ContentType = "application/PDF"; 
    Response.BinaryWrite(pdfData); 
} 
3

あなたはheap fragmentation(特にサーバー側のコードを持つ)を避けるため、巨大なバイト配列を割り当てないようにしたい場合は、ストリーミングを行うことができ、このような何か:

 using (SqlConnection cnx = new SqlConnection(@"your connection string")) 
     { 
      cnx.Open(); 
      using (SqlCommand cmd = cnx.CreateCommand()) 
      { 
       cmd.CommandText = "SELECT [File] FROM [com].[catalog1] WHERE [FileName] = @filename"; 
       cmd.Parameters.AddWithValue("filename", Request.QueryString["filename"]); 

       // sequential access is used for raw access 
       using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) 
       { 
        if (reader.Read()) 
        { 
         // must be lower than 85K (to avoid Large Object Heap fragmentation) 
         byte[] chunk = new byte[0x10000]; 
         long read; 
         long offset = 0; 
         do 
         { 
          read = reader.GetBytes(0, offset, chunk, 0, chunk.Length); 
          if (read > 0) 
          { 
           Response.OutputStream.Write(chunk, 0, (int)read); 
           offset += read; 
          } 
         } 
         while (read > 0); 
         Response.AddHeader("Content-Type", "application/pdf"); 
         Response.AddHeader("Content-Disposition", "inline; filename=" + Request.QueryString["filename"] + ".pdf");       
        } 
       } 
      } 
     } 

そして、あなたが同じファイルを提供する場合多くの場合、このファイルをサーバーの一部のCacheディレクトリに直接書き込んでから、その後のリクエストで再利用することをお勧めします。可能な場合はカーネルモードを使用してパフォーマンスが最も良いResponse.TransmitFile APIです。

関連する問題