Динамическое рендеринг asp: изображение из записи BLOB в ASP.NET

Я хочу добиться этого. Я хочу дать пользователю возможность загрузить файл изображения, сохранить изображение в BLOB в SQL Server, а затем использовать это изображение в качестве логотипа на других страницах сайта.

Я сделал это, используя

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

но для этого я использую элемент управления User в том месте, где я хочу показать изображение. Я хочу сделать это, если возможно, используя asp: Image control или даже чистый старый элемент управления html. Возможно ли это?

Спасибо всем

Ответы

Ответ 1

Добавьте "общий обработчик" в свой веб-проект, назовите его что-то вроде 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 требуется, чтобы поисковый поток был сохранен).

Ответ 2

Вы можете 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 в коде, если необходимо.

Ответ 3

Вы не хотите показывать капли из базы данных без кэширования на стороне клиента.

Вам потребуется обработать следующие заголовки для поддержки кеширования на стороне клиента:

  • ETag
  • Истекает
  • Last-Modified
  • Если-Match
  • If-None-Match
  • If-Modified-Since
  • Если-Unmodified-С
  • Unless-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

Ответ 4

Использование 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 или в этом примере в вашей веб-форме ASP.NET вы можете заполнить Image Control с помощью URL-адреса для вашего метода следующим образом:

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

Вуаля. Не требуется HttpModules.

Ответ 6

Добавьте код в обработчик, чтобы вернуть байты изображения с соответствующим типом mime. Затем вы можете просто добавить URL-адрес к своему обработчику, как образ. Например:

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

Имеют смысл?