2009-07-08 1 views
1

aspnet 2.0 페이지 지시문에서 출력 캐시 매개 변수를 사용하는 데 문제가 있습니다. 선택한 이미지의 값을 저장하기 위해 세션 변수를 사용하고 있습니다. 페이지 지시어에서 출력 캐시가 true로 설정되면 데이터 목록의 동적 컨트롤이 작동하지 않는 것 같습니다. 페이지 지시어를 사용하지 않으려면 이미지를 별도로 캐시하는 방법이 있습니까?SQl Server 2005 데이터베이스 호출에서 이미지를 캐시하는 방법은 무엇입니까?

DataList에 코드

"RepeatColumns ="6 "의 cellpadding ="8 "CellSpacing ="8 "눈금 =" "SelectedItemStyle-의 BackColor ="#의 33ff66 모두 "OnSelectedIndexChanged ="dtlImages_SelectedIndexChanged "OnItemCommand ="dtlImages_ItemCommand "> 'RUNAT = "서버">
'ID = "lblDescription"글꼴 - 굵게 = "진정한"글꼴 크기 = "12 픽셀"글꼴 - 이름 = "굴림">

데이터베이스에서 화상을 검색

코드

보호 보이드를 Page_Load (객체 송신자 경우 System.EventArgs E) { 문자열 strImageID = Request.QueryString을 [ "ID"];

 string wf4uConnect = System.Configuration.ConfigurationManager.ConnectionStrings["wf4uConnectionString"].ConnectionString; 
     System.Data.SqlClient.SqlConnection wf4uConn = new System.Data.SqlClient.SqlConnection(wf4uConnect); 

     System.Data.SqlClient.SqlCommand myCommand = new SqlCommand("Select ImageFile, ImageType from wf4u_ImageThumb Where ImageId =" + strImageID, wf4uConn); 

     wf4uConn.Open(); 

     SqlDataReader byteReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection); 

     while ((byteReader.Read())) 
     { 
      Response.BinaryWrite((byte [])byteReader.GetValue(0)); 
      Response.ContentType = (string)byteReader.GetValue(1); 
     } 

     wf4uConn.Close(); 
    } 

이미지가 웹 페이지에로드 될 때 이미지를 캐시하기 위해 http 컨텍스트 개체를 구현했습니다.

공용 이미지 목록 (문자열 clientName) { HttpContext context = HttpContext.Current;

 if((context.Cache["ImageIdList" + clientName] == null)) 
     { 
      string wf4uConnect = System.Configuration.ConfigurationManager.ConnectionStrings["wf4uConnectionString"].ConnectionString; 
      System.Data.SqlClient.SqlConnection wf4uConn = new System.Data.SqlClient.SqlConnection(wf4uConnect); 
      string queryStr = "SELECT ImageId FROM wf4u_imageThumb WHERE ClientName = @ClientName"; 
      SqlCommand ImageIdComm = new System.Data.SqlClient.SqlCommand(queryStr, wf4uConn); 
      ImageIdComm.Parameters.Add("@ClientName", SqlDbType.VarChar).Value = clientName; 

      wf4uConn.Open(); 

      SqlDataReader ImageIdReader = ImageIdComm.ExecuteReader(); 

      if (ImageIdReader.Read()) 
      { 
       _ImageId = ImageIdReader.GetInt32(0); 
       _ClientName = ImageIdReader.GetString(1); 

       context.Cache.Insert("ImageIdList" + clientName, this, null, DateTime.Now.AddSeconds(600), TimeSpan.Zero); 
      } 

      wf4uConn.Close(); 
     } 
     else 
     { 
      ImageList list = (ImageList)context.Cache["ImageIdList" + clientName]; 

      _ImageId = list.ImageId; 
      _ClientName = list.ClientName; 
     } 
    } 

모든 의견을 환영합니다.

당신이 볼 Cache 객체를 사용할 수 있습니다
+0

RJ : 문제와 관련된 몇 가지 코드를 게시 할 수 있습니까?아마도 출력 지시어, 데이터리스트, 바인딩 코드 또는 Session 객체에 저장하는 것일까? –

+0

이것이 첫 번째 질문이며 추가 코드를 게시 할 때 약간 분실됩니다. 이 설명 섹션은 600 자로 제한됩니다. 댓글에 게시물을 추가하려면 어떻게합니까? 나는 여기의 도크 인 것 같은 느낌이 든다. 그래서 나는 그 비행기를 가져갈 것이다. – rjsteward

+1

가장 쉬운 방법은 질문을 편집 한 다음 주석의 관련 부분을 인용하는 것입니다. – devstuff

답변

0

당신은이 같은 비동기 처리기를 구현할 수 있습니다.

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

public class FileHandler : IHttpAsyncHandler 
{ 
    #region Variables 
    private HttpContext _currentContext = null; 

    protected SqlCommand _command = null; 
    protected delegate void DoNothingDelegate(); 
    #endregion 

    public void ProcessRequest(HttpContext context) 
    { 
    } 

    public void DoNothing() 
    { 
    } 

    public bool IsReusable 
    { 
     get { return false; } 
    } 

    #region IHttpAsyncHandler Members 
    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) 
    { 

     _currentContext = context; 

     int imageId; 
     if (int.TryParse(context.Request.QueryString["imageId"], out imageId)) 
     { 
      // begin get file - make you own 
      // return FileController.BeginGetFile(out _command, cb, extraData, imageId); 
     } 
     else 
     { 
      DoNothingDelegate doNothingDelegate = new DoNothingDelegate(DoNothing); 

      return doNothingDelegate.BeginInvoke(cb, extraData); 
     } 
    } 

    public void EndProcessRequest(IAsyncResult result) 
    { 
     File file = null; 
     if (null != _command) 
     { 
      try 
      { 
       // end get file - make your own 
       // file = FileController.EndGetFile(_command, result); 
      } 
      catch { } 
     } 

     if (null != file) 
     { 
      // in my case File entity may be stored as a binary data 
      //or as an URL 
      // here is URL processing - redirect only 
      if (null == file.Data) 
      { 
       _currentContext.Response.Redirect(file.Path); 
      } 
      else 
      { 
       _currentContext.Response.ContentType = file.ContentType; 
       _currentContext.Response.BinaryWrite(file.Data); 
       _currentContext.Response.AddHeader("content-disposition", "filename=\"" + file.Name + (file.Name.Contains(file.Extension) ? string.Empty : file.Extension) + "\""); 
       _currentContext.Response.AddHeader("content-length", (file.Data == null ? "0" : file.Data.Length.ToString())); 

      } 

      _currentContext.Response.Cache.SetCacheability(HttpCacheability.Private); 
      _currentContext.Response.Cache.SetExpires(DateTime.Now); 
      _currentContext.Response.Cache.SetSlidingExpiration(false); 
      _currentContext.Response.Cache.SetValidUntilExpires(false); 
         _currentContext.Response.Flush(); 
     } 
     else 
     { 
      throw new HttpException(404, HttpContext.GetGlobalResourceObject("Image", "NotFound") as string); 
     } 
    } 
    #endregion 
}

그리고 필요한 값을 설정하십시오. 캐시 헤더에.

편집 : 캐시 개체를 사용하는 대신 머리글을 사용하는 것이 좋습니다.

+0

귀하의 도움을 크게 받으실 수 있습니다. 감사 – rjsteward

0

내가 할 방법을 것은 데이터베이스에서 비트를 읽는 HTTP 처리기를 사용하는 것입니다, 이미지 -에서 - 더 - 데이터베이스가 해당 클라이언트 측 설정 응답에 헤더를 캐싱합니다. 또한 If-Modified-Since 헤더를 지원하여 필요하지 않은 경우 BLOB 전송을 억제합니다.

다음 페이지에는 이미지 ID가있는 처리기에 대한 링크 만 있습니다. ID가 정수이거나 ID 형식이 무엇이든간에 유효성을 확인하는 데주의해야합니다. 공용 사이트는 수많은 SQL 주입 스타일 해킹 시도를받습니다.

ID를 변경 내 현재 디자인에 대한

이미지가 수정되기 때문에 캐싱 시간이 긴 것이, 예를 들어, 한 달 또는 년으로 설정 될 수있는 경우