从ASP.NET中的BLOB条目动态渲染asp:Image

时间:2020-03-05 18:41:54  来源:igfitidea点击:

我要实现的是这个。我想让用户能够上传图像文件,将图像存储在SQL Server的BLOB中,然后将该图像用作站点其他页面中的徽标。

我已经通过使用

Response.Clear();
   Response.ContentType = "image/pjpeg";
   Response.BinaryWrite(imageConents);
   Response.End();

但是要做到这一点,我在要显示图像的地方使用了用户控件。如果可能的话,我想使用asp:Image控件,甚至是纯旧的html图像控件。这可能吗?

谢谢你们

解决方案

回答

实际上,我们刚刚发布了一些类来帮助解决此类问题:

http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16449

具体来说,请检查DatabaseImage示例。

回答

我们可以将BASE64图像的内容直接编码为SRC属性,但是,我相信只有Firefox才能将其解析回图像。

我通常要做的是创建一个非常轻量级的HTTPHandler来提供图像:

using System;
using System.Web;

namespace Example
{  
    public class GetImage : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.QueryString("id") != null)
            {
                Blob = GetBlobFromDataBase(id);
                context.Response.Clear();
                context.Response.ContentType = "image/pjpeg";
                context.Response.BinaryWrite(Blob);
                context.Response.End();
            }
        }

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

我们可以在img标签中直接引用它:

<img src="GetImage.ashx?id=111"/>

或者,我们甚至可以创建一个为我们执行此操作的服务器控件:

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Example.WebControl
{

    [ToolboxData("<{0}:DatabaseImage runat=server></{0}:DatabaseImage>")]
    public class DatabaseImage : Control
    {

        public int DatabaseId
        {
            get
            {
                if (ViewState["DatabaseId" + this.ID] == null)
                    return 0;
                else
                    return ViewState["DataBaseId"];
            }
            set
            {
                ViewState["DatabaseId" + this.ID] = value;
            }
        }

        protected override void RenderContents(HtmlTextWriter output)
        {
            output.Write("<img src='getImage.ashx?id=" + this.DatabaseId + "'/>");
            base.RenderContents(output);
        }
    }
}

这可以像

<cc:DatabaseImage id="db1" DatabaseId="123" runat="server/>

当然,我们可以根据需要在代码背后设置databaseId。

回答

在Web项目中添加一个"通用处理程序",将其命名为Image.ashx。像这样实现它:

public class ImageHandler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        using(Image image = GetImage(context.Request.QueryString["ID"]))
        {    
            context.Response.ContentType = "image/jpeg";
            image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
        }
    }

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

现在只需实现GetImage方法以使用给定的ID加载图像,就可以使用

<asp:Image runat="server" ImageUrl="~/Image.ashx?ID=myImageId" />

显示它。我们可能还想考虑在处理程序中实现某种形式的缓存。请记住,如果要将图像格式更改为PNG,则需要使用中间的MemoryStream(因为PNG需要保存可搜索的流)。

回答

将代码添加到处理程序中,以返回具有适当mime类型的图像字节。然后,我们可以将网址添加到处理程序中,就像它是图像一样。例如:

<img src="myhandler.ashx?imageid=5">

有道理?

回答

我们不希望在不实施客户端缓存的情况下从数据库提供Blob。

我们将需要处理以下标头以支持客户端缓存:

  • 标签
  • 过期时间
  • 最后修改
  • 如果匹配
  • 如果不匹配
  • If-Modified-Since
  • 如果未修改,因为
  • 除非修改自

对于执行此操作的http处理程序,请签出:
http://code.google.com/p/talifun-web/wiki/StaticFileHandler

它有一个很好的助手来提供内容。将数据库流传递给它应该很容易。它还进行服务器端缓存,这应有助于减轻数据库的压力。

如果我们决定提供来自数据库,pdf或者大文件的流内容,则该处理程序还支持206个部分请求。

它还支持gzip和deflate压缩。

这些文件类型将受益于进一步的压缩:

  • css,js,htm,html,swf,xml,xslt,txt
  • doc,xls,ppt

有些文件类型无法从进一步压缩中受益:

  • pdf(导致IE中某些版本出现问题,并且通常压缩得很好)
  • png,jpg,jpeg,gif,ico
  • WAV,MP3,M4A,AAC(WAV通常被压缩)
  • 3gp,3g2,asf,avi,dv,flv,mov,mp4,mpg,mpeg,wmv
  • zip,rar,7z,arj