2013-05-08 70 views
1

我在使用C#的.NET应用程序中显示来自SQL Server数据库的图像时出现了一些问题。我已经保存了图像的保存部分,它将图像作为数据库中的一系列脚本存储,但现在我遇到了试图显示它的问题。这是我有:C#显示来自数据库的图像

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

public class ShowImage : IHttpHandler 
{ 
    public void ProcessRequest(HttpContext context) 
    { 
     Int32 empno; 
     if (context.Request.QueryString["id"] != null) 
      empno = Convert.ToInt32(context.Request.QueryString["id"]); 
     else 
      throw new ArgumentException("No parameter specified"); 

     context.Response.ContentType = "image/jpeg"; 
     Stream strm = ShowEmpImage(empno); 
     byte[] buffer = new byte[4096]; 
     int byteSeq = strm.Read(buffer, 0, 4096); 

     while (byteSeq > 0) 
     { 
      context.Response.OutputStream.Write(buffer, 0, byteSeq); 
      byteSeq = strm.Read(buffer, 0, 4096); 
     } 
     //context.Response.BinaryWrite(buffer); 
    } 

    public Stream ShowEmpImage(int empno) 
    { 
     string conn = CodProbs.Main.GetDSN(); 
     SqlConnection connection = new SqlConnection(conn); 
     string sql = "SELECT CoverPhoto FROM Galleries WHERE GalleryID = @GalleryID"; 
     SqlCommand cmd = new SqlCommand(sql, connection); 
     cmd.CommandType = CommandType.Text; 
     cmd.Parameters.AddWithValue("@GalleryID", empno); 
     connection.Open(); 
     byte[] img =                 System.Text.Encoding.Unicode.GetBytes(Convert.ToString(cmd.ExecuteScalar())); 
    try 
    { 
     return new MemoryStream((byte[])img); 
    } 
    catch 
    { 
     return null; 
    } 
    finally 
    { 
     connection.Close(); 
    } 
} 

public bool IsReusable 
{ 
    get 
    { 
     return false; 
    } 
} 

这不会导致任何语法错误,似乎它应该工作。使用调试器完成它之后,我可以看到它从数据库中获取了正确的数据。但是,我收到以下错误:“图像...无法显示,因为它包含错误。”

关于这个问题的任何想法?

UPDATE存储图像

public static int AddGallery(GalleryDS galleryDS) 
     { 
      DataRow gallery = galleryDS.Tables[0].Rows[0]; 
      int result = 0; 
      string sql = @"insert into Galleries (Title, Description,  GalleryCategoryID, CreateDate, CreatedBy, CoverPhoto) 
         values (@Title, @Description, @GalleryCategoryID, @CreateDate, @CreatedBy, @CoverPhoto) 
         select scope_identity()"; 

     using (SqlConnection conn = new SqlConnection(Main.GetDSN())) 
     { 
      SqlCommand command = new SqlCommand(sql, conn); 
      command.Parameters.AddWithValue("@Title", gallery["Title"]); 
      command.Parameters.AddWithValue("@Description", gallery["Description"]); 
      command.Parameters.AddWithValue("@GalleryCategoryID", 0); 
      command.Parameters.AddWithValue("@CreateDate", DateTime.Now); 
      command.Parameters.AddWithValue("@CreatedBy", gallery["CreatedBy"]); 
      command.Parameters.Add("@CoverPhoto", SqlDbType.VarBinary, Int32.MaxValue); 
      command.Parameters["@CoverPhoto"].Value = gallery["CoverPhoto"]; 
      conn.Open(); 
      result = Convert.ToInt32(command.ExecuteScalar()); 
      conn.Close(); 
     } 
     return result; 
    } 
+3

你只能分配4096个字节 - 这足够吗?如果图像更大,我想知道那里是否存在腐败现象? – 2013-05-08 16:35:08

+0

你的代码不完整。 'byte [] img ='之后会发生什么? – 2013-05-08 16:44:47

+0

byte [] img = System.Text.Encoding.Unicode.GetBytes(Convert.ToString(cmd.ExecuteScalar())); – user2363182 2013-05-08 16:49:58

回答

0

方法ShowEmpImage不应将其转换为一个流,然后把它写。这是浪费时间。

更改定义:

public Byte[] ShowEmpImage(int empno) { 
    string sql = "SELECT CoverPhoto FROM Galleries WHERE GalleryID = @GalleryID"; 
    Byte[] result = null; 

    using (SqlConnection conn = new SqlConnection(CodProbs.Main.GetDSN())) { 
     using(SqlCommand cmd = new SqlCommand(sql, conn)) { 
      cmd.CommandType = CommandType.Text; 
      cmd.Parameters.AddWithValue("@GalleryID", empno); 
      conn.Open(); 
      result = (Byte[])cmd.ExecuteScalar(); 
     } 
    } 

    return result; 
} 

要调用它使用以下命令:

Byte[] empImage = null; 
    empImage = ShowEmpImage(empno); 
    context.Response.Buffer = true; 
    context.Response.Clear(); 
    context.Response.ContentType = "image/jpeg"; 
    context.Response.Expires = 0; 
    context.Response.AddHeader("Content-Disposition", "attachment;filename=yourimagename.jpg"); 
    context.Response.AddHeader("Content-Length", empImage.Length.ToString()); 
    context.Response.BinaryWrite(empImage); 

边注:始终环绕非托管对象与using条款。它清理完后,你只是一个很好的做法。尤其适用于数据库连接

+0

这绝对更有意义,谢谢。尽管如此,仍然遇到同样的错误。 – user2363182 2013-05-08 16:50:50

+0

@ user2363182:见上。现在,如果由于某种原因,您仍然收到错误,那么我会看看在SQL Server中存储图像的部分。很可能您没有放入整个图像。 – NotMe 2013-05-08 16:52:25

+0

另请注意,此版本将文件和大小的名称写入浏览器。这有助于浏览器知道如何处理它。 – NotMe 2013-05-08 16:56:31

相关问题