从ASP.NET中的BLOB条目动态渲染asp:Image
我要实现的是这个。我想让用户能够上传图像文件,将图像存储在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