Как загрузить изображение в ASP.NET из базы данных в виде файла в веб-браузере? - PullRequest
2 голосов
/ 10 ноября 2010

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

Например, в Firefox, если вы зайдете в File-> Open File ... и выберите изображение на вашем компьютере, оно загрузит его в новое окно и изменит его размер при перетаскивании полос прокрутки. Моя проблема заключается в том, как получить изображение для загрузки из базы данных SQL Server в браузер в виде файла? У меня есть следующий код в форме, где пользователь щелкает представление в GridView:

<script type="text/javascript">
    function ShowImageInNewPage(url_add) {
        window.open(url_add, 'ViewScreenshot', 'resizable=yes,scrollbars = yes');
    }
</script>

<asp:GridView 
 ID="grdTrades" 
 runat="server" 

 <... removed some properties for brevity ...>
 >
 <Columns>
  <asp:CommandField ShowSelectButton="true" ButtonType="Link" SelectText="Select" /> 

  <.. removed some columns for brevity ...>

  <asp:TemplateField HeaderText="Screenshot" >
   <ItemTemplate>
    <input type="button" size="x-small" value="View" onclick="javascript:ShowImageInNewPage('DisplayImage.aspx?screenshotId=<%# Eval("screenshotId") %>');" />
   </ItemTemplate>
  </asp:TemplateField>
 </Columns>
</asp:GridView>

DisplayImage.aspx имеет этот код:

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {        
        if (Request.QueryString["screenshotId"] != null)
        {            
            int screenshotId= int.Parse(Request.QueryString["screenshotId"]);
            imgScreenshot.ImageUrl = "App_Handlers/ImageHandler.ashx?screenshotId=" + screenshotId;            
        }
    }    
</script>

<html>
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Image ID="imgScreenshot" runat="server" />
    </div>
    </form>
</body>
</html>

App_Handlers / ImageHandler.ashx имеет этот код:

<%@ WebHandler Language="C#" Class="ImageHandler" %>

using System;
using System.Web;
using System.Data;
using DatabaseComponent;

public class ImageHandler : IHttpHandler {

    public void ProcessRequest (HttpContext context) {

        if (context.Request.QueryString["screenshotId"] != null)
        {
            int screenshotId = int.Parse(context.Request.QueryString["screenshotId"]);

            DBUtil DB = new DBUtil();
            DataTable dt = DB.GetScreenshot(screenshotId);

            if (dt != null)
            {
                Byte[] bytes = (Byte[])dt.Rows[0]["screenshot"];
                context.Response.Buffer = true;
                context.Response.Charset = "";
                context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
                context.Response.ContentType = dt.Rows[0]["contentType"].ToString();
                context.Response.AddHeader("content-disposition", "attachment;filename=" + dt.Rows[0]["fileName"].ToString());
                context.Response.BinaryWrite(bytes);               
                context.Response.Flush();
                context.Response.End();
            }
        }        
    }

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

Вот заголовки ответа для DisplayImage.aspx

Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 10 Nov 2010 13:13:37 GMT
X-AspNet-Version: 4.0.30319
Transfer-Encoding: chunked
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: image/JPG
Connection: Close

Я изменил свой первоначальный вопрос, чтобы теперь использовать обработчик изображений, спасибо @leppie. Спасибо за внимание!

UPDATE

Я теперь изменил DisplayImage.aspx на этот код, но теперь я получаю немного странное поведение. Когда я нажимаю на ссылку с изображением, эта страница загружается, и Firefox спрашивает, хочу ли я сохранить DisplayImage.aspx. Что здесь происходит? Как я могу заставить Firefox загрузить изображение в виде файла?

DisplayImage.aspx:

<%@ Page Language="C#" ContentType="image/*"  %>

<script runat="server">        
</script>

<html>
<head runat="server">
    <title></title>
</head>
<body>
    <img  src="App_Handlers/ImageHandler.ashx?screenshotId=<%=Request.QueryString["screenshotId"]%>" /> 
</body>
</html>

Если я удаляю ContentType из объявления страницы, изображение загружается в новое окно, однако изображение не будет масштабироваться и не будет изменять свой размер. Вытаскивая мои волосы ...

Ответы [ 4 ]

3 голосов
/ 10 ноября 2010

Вы не должны использовать страницу для возврата данных изображения. Вместо этого вы должны использовать HttpHandler. HttpHandler - это класс, который реализует интерфейс IHttpHandler. Интерфейс IHttpHandler имеет более низкий уровень, чем Page. Page фактически сам реализует IHttpHandler, но цель Page - вернуть html, поэтому его не следует использовать для возврата данных изображения.

1 голос
/ 10 ноября 2010

Если вы хотите сделать это, используя страницу (например, ImageLoad.aspx), тогда должно быть достаточно чего-то подобного в Page_Load:

protected void Page_Load(object sender, EventArgs e)
{
    HttpResponse response = HttpContext.Current.Response;

    response.Clear();
    response.ContentType = "image/png";

    Image outputImage = (Load your image here)
    MemoryStream ms = new MemoryStream();
    outputImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    ms.WriteTo(response.OutputStream);
    outputImage.Dispose();
    ms.Close();

    response.End();
}

В качестве альтернативы с обработчиком:

public class ImageHandler : IHttpHandler
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        try
        {
            HttpResponse response = context.Response;

            response.Clear();
            response.ContentType = "image/png";

            Image outputImage = (Load your image here)
            MemoryStream ms = new MemoryStream();
            outputImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            ms.WriteTo(response.OutputStream);
            outputImage.Dispose();
            ms.Close();

            response.End();
        }
        catch
        {
            context.Response.End();
        }
    }
}

Просто замените (Загрузите ваше изображение здесь) на соответствующий код, основанный на том, как вы указываете изображение (предположительно в качестве параметра запроса).

Как предлагается в других ответах, установите соответствующие заголовки кэширования для запроса, если вы хотите сохранить некоторые тактовые циклы.

0 голосов
/ 14 ноября 2010

Мне удалось решить это. Я могу полностью удалить DisplayImage.aspx и просто вызвать обработчик изображения прямо со своей вызывающей страницы, поэтому мой GridView теперь выглядит так:

<script type="text/javascript">
    function ShowImageInNewPage(url_add) {
        window.open(url_add, 'ViewScreenshot', 'resizable=yes,scrollbars = yes');
    }
</script>

<asp:GridView 
 ID="grdTrades" 
 runat="server" 

 <... removed some properties for brevity ...>
 >
 <Columns>
  <asp:CommandField ShowSelectButton="true" ButtonType="Link" SelectText="Select" /> 

  <.. removed some columns for brevity ...>

  <asp:TemplateField HeaderText="Screenshot" >
   <ItemTemplate>
    <input runat="server" visible='<%# Eval("screenshotId") != DBNull.Value %>' type="button" value='View...' onclick='<%# "ShowImageInNewPage(\"App_Handlers/ImageHandler.ashx?screenshotId=" + Eval("screenshotId") + "\")" %>' />
   </ItemTemplate>
  </asp:TemplateField>
 </Columns>
</asp:GridView>

Когда пользователь нажимает кнопку, изображение загружается в новое окно и его размер можно изменить на клиенте, перетаскивая угол окна. Спасибо всем за помощь в этом.

0 голосов
/ 10 ноября 2010

Как только вы получите байт [] из вашей базы данных

Установите для Response.MimeType подходящее значение, такое как «image / jpg» для изображений jpeg. Затем выполните Response.Write или Response.WriteBinary для записи.байта [] в ответ.

При желании установите заголовки кэширования, если вы хотите, чтобы браузер кэшировал файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...