【问题标题】:How to cache images from a SQl Server 2005 database call?如何缓存来自 SQl Server 2005 数据库调用的图像?
【发布时间】:2010-11-08 21:46:34
【问题描述】:

我在使用 aspnet 2.0 页面指令中的输出缓存参数时遇到问题。我正在使用会话变量来保存所选图像的值。当页面指令中的输出缓存设置为 true 时,数据列表中的动态控件似乎不起作用。有没有办法单独缓存图像以避免使用页面指令?

数据列表代码

" RepeatColumns="6" CellPadding="8" CellSpacing="8" GridLines="Both" SelectedItemStyle-BackColor="#33ff66" OnSelectedIndexChanged="dtlImages_SelectedIndexChanged" OnItemCommand="dtlImages_ItemCommand"> 'runat="服务器">
' ID="lblDescription" Font-Bold="True" Font-Size="12px" Font-Names="Arial">

从数据库中检索图像的代码

protected void Page_Load(object sender, 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 上下文对象来缓存加载到网页中的图像。

公共图像列表(字符串客户端名称) { HttpContext 上下文 = 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;
        }
    }

欢迎提出任何建议。

【问题讨论】:

  • RJ:你能发布一些与问题相关的代码吗?也许是输出指令、数据列表、绑定代码或保存到 Session 对象?
  • 这是我的第一个问题,我在发布附加代码时有点迷失了。此评论部分限制为 600 个字符。如何在您的评论中添加更多帖子?我在这里感觉自己像个笨蛋,所以我想我会接受的。
  • 最简单的方法是编辑您的问题,然后引用评论的相关部分。
  • 标签下方有一个编辑链接(C#、asp.net、sqlserver2005 等)。应该在重新标记和标记链接旁边。这将允许您发布和标记对问题的任何更改。

标签: c# asp.net sql-server-2005 caching


【解决方案1】:

您可以使用Cache 对象查看:ASP.NET Caching: Techniques and Best Practices

【讨论】:

    【解决方案2】:

    我从数据库中获取图像的方法是使用 HTTP 处理程序,该处理程序从数据库中读取位,并在响应中设置适当的客户端缓存标头。如果不需要,我还支持 If-Modified-Since 标头以禁止发送 blob。

    然后该页面仅包含指向带有图像 ID 的处理程序的链接(必须小心验证该 ID 是整数还是您要使用的任何 ID 格式 - 公共网站会遇到大量 SQL 注入式黑客攻击尝试。

    对于我当前的设计,如果图像被修改,ID 会发生变化,因此可以将缓存时间设置为较长的​​时间,例如一个月或一年。

    【讨论】:

      【解决方案3】:

      您可以像这样实现异步处理程序:

      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
      }

      并为缓存头设置必要的值。

      编辑:猜猜,在这种情况下,最好使用标头而不是使用缓存对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多