【问题标题】:Dynamically Rendering asp:Image from BLOB entry in ASP.NET动态呈现 asp:来自 ASP.NET 中 BLOB 条目的图像
【发布时间】:2010-09-06 12:26:21
【问题描述】:

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

我通过使用

做到了这一点
   Response.Clear();
   Response.ContentType = "image/pjpeg";
   Response.BinaryWrite(imageConents);
   Response.End();

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

【问题讨论】:

标签: asp.net


【解决方案1】:

将 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 填充图像控件,如下所示:

            this.imgExample.ImageUrl = "~/Items/Image/" + MyItem.Id.ToString();
            this.imgExample.Height = new Unit(120);
            this.imgExample.Width = new Unit(120);

瞧。不需要 HttpModules 麻烦。

【讨论】:

    【解决方案2】:

    您不希望在不实现客户端缓存的情况下从数据库提供 blob。

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

    • ETag
    • 过期
    • 最后修改
    • 如果匹配
    • 如果没有匹配
    • If-Modified-Since
    • If-Unmodified-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

    【讨论】:

    • 哇!这个问题已经一年多了!感谢您的回答,但是我已经解决了这个问题! +1 有据可查的答案。
    • 另外,您可以缓存到磁盘并允许 IIS 处理 ETag、Last-Modified 等。就像ImageResizing.net 一样。 IIS 在提供静态文件方面确实比托管代码具有良好的性能优势,即使使用最佳的 .NET 实现也是如此。
    • 这就是为什么我以可扩展的方式离线处理。 github.com/taliesins/talifun-commander
    【解决方案3】:

    您可以将图像的内容直接 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。

    【讨论】:

    • 什么是图像/pjpeg?这是 IE 中的错误,不是在服务器上使用的有效 mime 类型;)
    【解决方案4】:

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

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

    有意义吗?

    【讨论】:

      【解决方案5】:

      为您的 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 需要保存可搜索的流)。

      【讨论】:

      • 我知道这是旧的,但我想你有我在这里寻找的东西。我现在只是想念知识,想弄清楚。我已经写好了我的处理程序。这里是pastebin.com/m75e17237,我接到了那个处理程序的电话。它看起来像这样:pastebin.com/m63e1ebc3 但是当页面加载时,我只是得到丢失的图像小红色 X 框。我以前从未使用过处理程序,所以可能做错了什么。我注意到的一件事是,如果我在处理程序中设置断点,它永远不会到达那里。如果你有机会,任何建议都会很棒。 -会
      • @aape: 你在 web.config 中注册了处理程序吗?
      • 试图在这里找到我的问题的答案,我有两个图像,我想根据学生是否注册在一个视图上显示,我拥有的这个视图是强类型的,怎么能我让这个工作?
      【解决方案6】:

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

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

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

      【讨论】:

      • 链接失效
      • 不幸的是,CodePlex 几年前就关闭了,现在这个示例早已不复存在。此页面上勾选的答案中提供了解决方案。
      猜你喜欢
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多