2013-09-11 2 views
0

내 웹 응용 프로그램에서 사용자가 보고서를 보낼 수 있으며 데이터베이스 (SQL Server)에 최대 5 개의 이미지를 varbinary (MAX)로 삽입 할 수 있습니다. 지금은 사용자가 보낸 특정 보고서의 모든 이미지를 검색하는 방법을 찾고 있습니다. 이전에는 aspx 페이지를 통해 이미지 1을 1 회 검색했습니다. 하지만 사용자가 5에서 1 개의 이미지 만 삽입하면 문제가 발생했습니다. 내 4 개의 다른 이미지 태그는 null 이미지를 표시합니다. 그래서 이제는 단 하나의 이미지 태그로 보고서를 기반으로 이미지를 검색 할 수있는 방법을 찾고자합니다. 이미지가 이전에 보고서와 동일한 테이블에 저장되었으므로 이제 테이블을 2 개로 변경합니다. MemberReport는 보고서의 모든 세부 정보이며 MemberReportImage는 보고서의 모든 이미지입니다.데이터베이스에서 이미지 태그로 이미지 검색

아래 코드는 memberreportid를 이미지 태그로 사용하여 내 MemberReportImage 테이블에서 첫 번째 이미지를 검색하는 것을 허용하지만 이미지 태그보다 한 번에 같은 memberreportid를 가진 모든 이미지를 검색하려고합니다. 내가 생각하기에 모든 이미지를 얻기 위해서는 루프가 필요했지만 어떻게해야할지 모르겠습니다. 그래서 나는 이것을 도와 줄 사람이 필요합니다. 감사!

protected void Page_Load(object sender, EventArgs e) 
{ 
    string strQuery = "select image from MemberReportImage where memberreportid='" + Session["memberreportid"] + "'"; 
    SqlCommand cmd = new SqlCommand(strQuery); 
    DataTable dt = GetData(cmd); 
    if (dt != null) 
    { 
     download(dt); 
    } 
} 

private DataTable GetData(SqlCommand cmd) 
{ 
    DataTable dt = new DataTable(); 
    SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 
    SqlDataAdapter sda = new SqlDataAdapter(); 
    cmd.CommandType = CommandType.Text; 
    cmd.Connection = con; 
    try 
    { 
     con.Open(); 
     sda.SelectCommand = cmd; 
     sda.Fill(dt); 
     return dt; 
    } 
    catch 
    { 
     return null; 
    } 
    finally 
    { 
     con.Close(); 
     sda.Dispose(); 
     con.Dispose(); 
    } 
} 

private void download(DataTable dt) 
{ 
    // check if you have any rows at all 
    // no rows -> no data to convert! 
    if (dt.Rows.Count <= 0) 
     return; 

    // check if your row #0 even contains data -> if not, you can't do anything! 
    if (dt.Rows[0].IsNull("image")) 
     return; 

    Byte[] bytes = (Byte[])dt.Rows[0]["image"]; 
    Response.Buffer = true; 
    Response.Charset = ""; 
    Response.Cache.SetCacheability(HttpCacheability.NoCache); 
    Response.ContentType = "image/jpg"; 
    Response.BinaryWrite(bytes); 
    Response.End(); 
} 
+1

는 http://stackoverflow.com/questions/13104356/display-varbinary-as-a-downloadable-link/13104410#13104410를 참조 –

답변

2

거기에 묻는 것을 수행하는 사례가 많이 있습니다. 이 답변은 두 부분으로 나뉩니다. 먼저 (UI 페이지에서) 어떤 이미지가 있는지 파악하고 쿼리 결과에 따라 이미지를 숨기거나 숨길 필요가 있습니다. 다음으로 페이지 (또는 더 적절하게 HttpHandler)를 사용하여 페이지에 이미지를 표시해야합니다. 나는 아래의 간단한 샘플을 조롱했다. 나는 당신이 그것을 통해 읽을 수 있도록 코드를 주석하려고했습니다.

귀하의 aspx 페이지 (HTML)는

<form id="form1" runat="server"> 
    <div> 
     <asp:Image ID="Image1" runat="server" /> 
     <asp:Image ID="Image2" runat="server" /> 
     <asp:Image ID="Image3" runat="server" /> 
     <asp:Image ID="Image4" runat="server" /> 
     <asp:Image ID="Image5" runat="server" /> 
    </div> 
</form> 

이 5 개 이미지와 간단한 페이지입니다. 귀하의 페이지는 조금 더 복잡해 지겠지만 데모 용입니다. 그런 다음 페이지로드 이벤트 (또는 다른 이벤트)를 사용하여 데이터베이스의 이미지를 조회하고 업로드되지 않은 이미지를 숨 깁니다.

영문 페이지 (코드) 당신은 우리가 단순히 발견 된 ID를 기반으로 업로드하는 이미지를 찾기 위해 쿼리를하고있는 위에서 볼 수 있듯이

protected void Page_Load(object sender, EventArgs e) 
{ 
    Session["memberreportid"] = 1; //TODO: Remove this 
    var query = "SELECT TOP 1 * FROM MemberReport where [email protected]"; 

    //create the format string for each image. Note the last variable is {0} for additional formating 
    string imageSource = string.Format("/viewImage.ashx?memberreportid={0}&imageID={1}", Session["memberreportid"], "{0}"); 

    //set our URL to our Image handler for each image 
    Image1.ImageUrl = string.Format(imageSource, 1); 
    Image2.ImageUrl = string.Format(imageSource, 2); 
    Image3.ImageUrl = string.Format(imageSource, 3); 
    Image4.ImageUrl = string.Format(imageSource, 4); 
    Image5.ImageUrl = string.Format(imageSource, 5); 

    //execute our command. Note we are using parameters in our SQL to circumvent SQL injection 
    using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["conString"].ConnectionString)) 
    { 
     var cmd = new SqlCommand(query, con); 
     cmd.CommandType = System.Data.CommandType.Text; 
     cmd.CommandTimeout = 3000; 
     cmd.Parameters.AddWithValue("@p1", Session["memberreportid"]); 
     con.Open(); 
     var reader = cmd.ExecuteReader(); 
     while (reader.Read()) 
     { 
      //hide each image if the image is null or not a byte array (should always be a byte array) 

      if (reader["image1"] == null || !(reader["image1"] is byte[])) 
       Image1.Visible = false; 
      if (reader["image2"] == null || !(reader["image2"] is byte[])) 
       Image2.Visible = false; 
      if (reader["image3"] == null || !(reader["image3"] is byte[])) 
       Image3.Visible = false; 
      if (reader["image4"] == null || !(reader["image4"] is byte[])) 
       Image4.Visible = false; 
      if (reader["image5"] == null || !(reader["image5"] is byte[])) 
       Image5.Visible = false; 

      //we only want the first row so break (should never happen anyway) 
      break; 
     } 
     con.Close(); 
    } 
} 

. 이미지가 null의 경우 (또는 byte []가 아닌 경우), 이미지 컨트롤은 숨겨집니다.

마지막 부분은 HttpHandler (새 항목 목록의 GenericHandler)를 사용하고 있습니다. HttpHandler는 모든 페이지 생성 이벤트를 필요로하지 않고 HttpHandler 컨텍스트에 직접 연결할 수 있기 때문에 아마 여기있는 것이 가장 좋습니다. 여기에서 ASPx 페이지 (내 개인 구현)에서 수행하고자하는 모든 것을 거의 할 수 있습니다. 기본적으로 HttpHandler는 세션 상태에 액세스 할 수 없습니다.

viewImage.ashx (또는 원하는대로)라는 새 GenericHandler를 추가하고 다음 코드를 추가하십시오. 다시 읽음을 돕기 위해 주석이 달려 있습니다.

viewImage.ashx code.

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

namespace WebApplication1 
{ 
    /// <summary> 
    /// Summary description for viewImage 
    /// </summary> 
    public class viewImage : IHttpHandler 
    { 
     /// <summary> 
     /// process the request 
     /// </summary> 
     /// <param name="context">the current request handler</param> 
     public void ProcessRequest(HttpContext context) 
     { 
      ///extract our params from the request 
      int memberID = 0, imageID = 0; 
      if (!int.TryParse(context.Request["memberreportid"], out memberID) || 
       memberID <= 0 || 
       !int.TryParse(context.Request["imageID"], out imageID) || 
       imageID <= 0) 
      { 
       this.transmitError(); 
       return; 
      } 

      //build our query 
      var query = string.Format("SELECT TOP 1 image{0} FROM MemberReport where [email protected]", imageID); 

      //execute the query 
      using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["conString"].ConnectionString)) 
      { 
       try 
       { 
        var cmd = new SqlCommand(query, con); 
        cmd.CommandType = System.Data.CommandType.Text; 
        cmd.CommandTimeout = 3000; 
        //set the member command type 
        cmd.Parameters.AddWithValue("@p1", memberID); 
        con.Open(); 
        var reader = cmd.ExecuteReader(); 
        while (reader.Read()) 
        { 
         string psudoFileName = string.Format("memberReport_{0}_image{1}.png", memberID, imageID); 
         byte[] binary = reader[0] as byte[]; 
         context.Response.ContentType = "image/png"; 
         context.Response.AppendHeader("Content-Disposition", string.Format("filename=\"{0}\"", psudoFileName)); 
         context.Response.AppendHeader("Content-Length", binary.Length.ToString()); 
         context.Response.BinaryWrite(binary); 

         //todo: Implement your caching. we will use no caching 
         context.Response.Cache.SetCacheability(HttpCacheability.NoCache); 

         //we only want the first row so break (should never happen anyway) 
         break; 
        } 
        con.Close(); 
       } 
       catch (Exception ex) 
       { 
        //TODO: Maybe some logging? 

       } 
       this.transmitError(); 
      } 
     } 

     /// <summary> 
     /// transmits a non-image found 
     /// </summary> 
     void transmitError() 
     { 
      var context = HttpContext.Current; 
      if (context == null) 
       return; 
      //set the response type 
      context.Response.ContentType = "image/png"; 
      //set as no-cache incase this image path works in the future. 
      context.Response.Cache.SetCacheability(HttpCacheability.NoCache); 

      //transmit the no-image found error 
      context.Response.TransmitFile(context.Server.MapPath("no-image.png")); 
     } 

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

지금이 \ 당신이 페이지에 이미지를 표시 할 수-수있게 보여줄 필요가있는 모든 일 업로드되는 이미지를 숨겨야합니다.

희망이 도움이됩니다.

+0

미안 정말 어떻게 작동하는지하지 않습니다. 이 처음이 일을, 나는 너무 전에 GenericHandler (.ashx) 사용하지 마십시오. 어쩌면 나는 내 질문을 바꾸어야한다. – XiAnG

+0

ASHx 처리기를 사용하지 않아도 ASPx 페이지를 사용할 수 있습니다.기본적으로 이미지 url을 핸들러에 설정합니다. 핸들러는이 예에서 쿼리 문자열의 값을 전달합니다. 여기에서 멤버 ID와 이미지 ID를 파싱하고 바이트 배열로 데이터베이스의 이미지를 Http Response로 보냅니다. – Nico

관련 문제