2010-11-10 5 views
2

J'ai quelques images dans une base de données SQL Server. Je veux les afficher quand un utilisateur clique sur un bouton, mais je veux qu'ils se chargent dans le navigateur en tant que fichier de sorte que lorsque l'utilisateur redimensionne la fenêtre, les images se redimensionnent automatiquement. Par exemple, dans Firefox, si vous allez dans Fichier-> Ouvrir fichier ... et sélectionnez une image sur votre ordinateur, il la chargera dans une nouvelle fenêtre et la redimensionnera pour vous lorsque vous faites glisser les barres de défilement. Mon problème est, comment puis-je obtenir l'image à charger à partir d'une base de données SQL Server dans le navigateur en tant que fichier? Je le code suivant sur le formulaire où l'utilisateur clique voir dans un GridView:Comment charger une image dans ASP.NET à partir d'une base de données en tant que fichier dans un navigateur Web?

<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 a ce code:

<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 a ce code:

<%@ 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; 
     } 
    } 
} 

Voici les en-têtes de réponse pour 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 

J'ai modifié ma question initiale pour utiliser un gestionnaire d'image maintenant grâce à @leppie. Merci d'avoir regardé!

MISE À JOUR

J'ai maintenant changé DisplayImage.aspx à ce code, mais maintenant je reçois un comportement bizarre réel. Lorsque je clique sur un lien d'image, cette page se charge et Firefox demande si je veux enregistrer DisplayImage.aspx. Que se passe-t-il? Comment puis-je obtenir Firefox pour charger l'image en tant que fichier?

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> 

Si je retire ContentType de la page déclaration des charges d'image dans une nouvelle fenêtre mais l'image ne sera pas zoomer, et ne se redimensionner. Retirer mes cheveux ...

+0

Oui, vous avez besoin de 2. – leppie

+0

Il semble que personne ne sait comment charger une image à partir d'une base de données et la charger dans le navigateur en tant que fichier. Cela doit être un modèle commun, quelqu'un veut-il faire un autre essai? :-) –

+0

vous devez modifier l'en-tête de disposition de contenu à en ligne et inclure l'en-tête de longueur de contenu ainsi –

Répondre

0

J'ai réussi à résoudre ce problème. Je peux retirer DisplayImage.aspx complètement et il suffit d'appeler le gestionnaire d'images directement à partir de ma page d'appel, donc mon GridView ressemble maintenant à ceci:

<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> 

Lorsque l'utilisateur clique sur le bouton, l'image se charge dans une nouvelle fenêtre et peut être redimensionné sur le client en faisant glisser le coin de la fenêtre. Merci pour l'aide de tout le monde à ce sujet.

3

Vous ne devriez pas utiliser une page pour retourner les données d'image. Au lieu de cela, vous devriez utiliser un HttpHandler. Un HttpHandler est une classe qui implémente l'interface IHttpHandler. L'interface IHttpHandler est plus bas niveau que Page. Page implémente en fait IHttpHandler lui-même, mais le but de Page est de renvoyer html, c'est pourquoi vous ne devriez pas l'utiliser pour renvoyer des données d'image.

+0

Une page est tout aussi bonne, et probablement mieux de voir que vous n'avez pas besoin d'autorisations pour installer les gestionnaires/modifier le web.config. – leppie

+0

@leppie, vous n'avez pas besoin d'éditer web.config pour installer un httphandler. Un fichier .ashx fonctionne aussi bien. –

+0

OK, je peux réécrire en utilisant un fichier ashx, mais revenons à la question. Comment charger l'image dans le navigateur en tant que fichier et non en tant qu'image sur une page? –

0

Une fois que vous avez l'octet [] à partir de votre base de données

Définissez la Response.MimeType à la valeur appropriée telle que « image/jpg » pour les images jpeg Ensuite, faites un Response.Write ou Response.WriteBinary écrire l'octet [] à la réponse.

Vous pouvez également définir des en-têtes de cache si vous souhaitez que le navigateur mette en cache le fichier.

+0

Merci, mais comment puis-je afficher l'image? Quels changements dois-je apporter à DisplayImage.aspx? Actuellement, il est affiché dans un contrôle d'image, mais je ne veux pas le faire. –

1

Si vous voulez le faire en utilisant une page (par exemple, ImageLoad.ASPX) alors quelque chose comme ça dans Page_Load devrait suffire:

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(); 
} 

Alternativement avec un gestionnaire:

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(); 
     } 
    } 
} 

il suffit de remplacer (Chargez votre image ici) avec le code correspondant en fonction de la façon dont vous spécifiez l'image (probablement comme paramètre de demande).

Comme suggéré dans d'autres réponses, définissez des en-têtes de mise en cache pertinents sur la requête si vous souhaitez enregistrer des cycles d'horloge.

+0

Merci James, j'ai essayé votre code et il a le même effet que mon code. Essayez ceci: avec Firefox, ouvrez une image à partir de votre disque dur local, puis redimensionnez la fenêtre. L'image est redimensionnée automatiquement. Je veux que mon image se charge de ma base de données dans le navigateur de la même manière afin que le navigateur pense que c'est un fichier. La méthode que vous venez de me montrer, et ma méthode montrée dans ma question affiche simplement l'image mais quand je redimensionne le navigateur, l'image ne se redimensionne pas. Des idées pour résoudre le problème? –

+0

@James - Voici un exemple de chargement de mes images. Cliquez sur une image sur cette page puis redimensionnez votre navigateur pour voir ce que je veux dire. http://www.phpbb.com/community/viewtopic.php?f=6&t=2109563 –

+0

Je ne vois pas ce qui est spécial au sujet de la façon dont cette image est livrée. J'ai essayé d'ouvrir quelques images dans Firefox et ils s'ouvrent tous comme ça. Ils rétrécissent si la fenêtre du navigateur est plus petite, mais ne développez pas si elle est plus grande.Vous pouvez exécuter Live HTTP Headers dans Firefox et voir exactement quels en-têtes sont envoyés avec l'image - ce que j'ai fait ici et encore - rien d'inhabituel n'y saute. Peut-être essayer de comparer l'en-tête de l'en-tête avec l'image que vous servez. –

Questions connexes