我想要实现的是这个。我想让用户能够上传图像文件,将图像存储在SQL Server中的BLOB中,然后将此图像用作网站其他页面中的徽标。
我这样做是通过使用
Response.Clear();
Response.ContentType = "image/pjpeg";
Response.BinaryWrite(imageConents);
Response.End();
但要做到这一点,我在我想要显示图像的地方使用用户控件。我想尽可能使用asp:Image控件,甚至是纯旧的html图像控件。这可能吗?
在Web项目中添加“Generic Handler”,将其命名为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需要保存可搜索流)。
您可以将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/>
当然,您可以根据需要在后面的代码中设置数据库ID。
您不希望在不实现客户端缓存的情况下从数据库提供blob。
您需要处理以下标头以支持客户端缓存:
对于执行此操作的http处理程序,请查看:http://code.google.com/p/talifun-web/wiki/StaticFileHandler
它有一个很好的帮助来提供内容。将数据库流传递给它应该很容易。它还可以进行服务器端缓存,这有助于减轻数据库的一些压力。
如果您决定从数据库,pdfs或大文件提供流内容,则处理程序还支持206个部分请求。
它还支持gzip和deflate压缩。
这些文件类型将受益于进一步压缩:
有些文件类型无法从进一步压缩中受益:
使用ASP.Net和MVC这很容易。您使用如下方法对控制器进行编码:
public FileContentResult Image(int id)
{
//Get data from database. The Image BLOB is return like byte[]
SomeLogic ItemsDB= new SomeLogic("[ImageId]=" + id.ToString());
FileContentResult MyImage = null;
if (ItemsDB.Count > 0)
{
MyImage= new FileContentResult(ItemsDB.Image, "image/jpg");
}
return MyImage;
}
在ASP.NET Web视图中或在此示例中,在ASP.NET Web窗体中,您可以使用以下方法的URL填充Image Control:
this.imgExample.ImageUrl = "~/Items/Image/" + MyItem.Id.ToString();
this.imgExample.Height = new Unit(120);
this.imgExample.Width = new Unit(120);
瞧。不需要HttpModules麻烦。
我们实际上刚刚发布了一些有助于完成这类事情的类:
http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16449
具体来说,请查看DatabaseImage示例。
将代码添加到处理程序以使用适当的mime类型返回图像字节。然后你可以将url添加到你的处理程序,就像它是一个图像。例如:
<img src="myhandler.ashx?imageid=5">
合理?