2009-07-08 2 views
1

aspnet 2.0ページディレクティブで出力キャッシュパラメータを使用する際に問題があります。私は選択された画像の値を保持するためにセッション変数を使用しています。ページディレクティブで出力キャッシュがtrueに設定されていると、データリストの動的制御が機能していないようです。ページディレクティブを使わないようにイメージを別々にキャッシュする方法はありますか?SQl Server 2005データベースコールからイメージをキャッシュする方法は?

データリストコード

"RepeatColumns =" 6" CellPadding作業= "8" CELLSPACING = "8" グリッド線= "両方" SelectedItemStyle-のBackColor = "#1 33ff66" OnSelectedIndexChanged = "dtlImages_SelectedIndexChanged" OnItemCommand = "dtlImages_ItemCommand"> 'にrunat = "サーバー">
' ID = "lblDescription" フォント・太字= "真" のfont-size = "12ピクセル" フォント名= "Arialの">

データベースから画像を検索

コード

保護されたボイドを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コンテキストオブジェクトを実装しました。

public ImageList(string 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; 
     } 
    } 

いずれの提案も歓迎されます。

+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 
}

必要な値を設定するキャッシュヘッダーに転送します。

EDIT:この場合、Cacheオブジェクトを使用する代わりにヘッダーを使用する方がよいでしょう。

+0

お手数をおかけしますようお願い申し上げます。ありがとう – rjsteward

0

私は画像-から-データベースの事は、データベースからビットを読み取るHTTPハンドラを使用することで、適切なクライアント側の設定のやり方応答のヘッダーをキャッシュします。私はまた、If-Modified-Sinceヘッダーをサポートして、必要でない場合にBLOBの送信を抑制します。

このページには、イメージIDを持つハンドラへのリンクがあります(IDが整数または何らかのID形式であることを検証するために注意する必要があります)。公開サイトでは多数のSQL注入スタイルのハック試行が行われます。

私の現在の設計IDの変更については

イメージが変更されたので、キャッシュ時間が長いものに設定することができ、例えば、月または年あれば

関連する問題