Affichage dynamique d'images dérivées d'un tableau d'octets sur une page
Question
J'appelle un service Web qui renvoie une quantité inconnue d'images sous la forme d'une collection de tableaux d'octets. (Je ne peux pas changer cela)
Je dois afficher chaque image sur une seule page Web aspx.
J'utilise actuellement le contrôle Microsoft.Web.GeneratedImage; http://www.codeplex.com/aspnet/Release/ProjectReleases. aspx? ReleaseId = 16449 pour afficher les images.
Le problème est que, puisque le contrôle appelle un fichier de code séparé pour charger le contenu de l'image, j'utilise l'état de session pour stocker le bytearray, ce qui ne me fait pas très plaisir.
Voici du code de mon projet de test;
Private Sub btnGetChart_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGetChart.Click
Dim reportHub As New HubWrapper
Dim repCharts() As ReportHub.Chart = reportHub.ReportHubChart(Me.ddlReports.SelectedValue, ViewState("params"))
For Each chart As ReportHub.Chart In repCharts
Dim sessionKey As String = "img" & System.Guid.NewGuid().ToString
Dim imgParam As New Microsoft.Web.ImageParameter()
imgParam.Name = "sessionVar"
imgParam.Value = sessionKey
Session(sessionKey) = chart.ChartData
Dim img As New Microsoft.Web.GeneratedImage
img.ImageHandlerUrl = "~/chartImageHandler.ashx"
img.Parameters.Add(imgParam)
phChart.Controls.Add(img)
Next
End Sub
<%@ WebHandler Language="VB" Class="chartImageHandler" %>
Imports System
Imports System.Collections.Specialized
Imports System.Drawing
Imports System.Web
Imports Microsoft.Web
Public Class chartImageHandler
Inherits ImageHandler
Implements IRequiresSessionState
Public Sub New()
MyBase.New()
'Set caching settings and add image transformations here
'EnableServerCache = True
End Sub
Public Overrides Function GenerateImage(ByVal parameters As NameValueCollection) As ImageInfo
Dim byteArry As Byte() = CType(HttpContext.Current.Session(parameters("sessionVar")), Byte())
HttpContext.Current.Session.Remove(parameters("sessionVar"))
Return New ImageInfo(byteArry)
End Function
End Class
Quel est le moyen le plus élégant d'y parvenir?
Toute entrée bienvenue !!!
EDIT: Informations supplémentaires;
- Les images du webservice sont provenant de SQL Reporting Services.
- Les images seraient généralement changer tout le temps (pas de vrai exigence de mise en cache).
- Les images seraient spécifiques à l'utilisateur.
- Le service Web n'est appelé qu'une fois par page.
- je suis en train de jeter l'image de état de session après la génération image l'utilise, car l'image ne sera pas besoin d'être revu pour un pendant que.
La solution
Vous pouvez incorporer les données d'image directement dans la source de la page à l'aide du schéma data:
. Voici la description de Wikipedia . Toutefois, cela ne fonctionne pas avec les versions d’Internet antérieures à la version 8, ce qui pourrait rendre votre situation inacceptable.
Autres conseils
Je suppose que vous souhaitez appeler votre service Web une seule fois par demande de page. En fait, il serait bon de mettre en cache le tableau d'octets, afin que le service Web ne soit pas appelé à nouveau si l'utilisateur s'éloigne momentanément de la page puis revient. Dans ce cas, la sauvegarde du tableau d'octets dans la session est inévitable. Si vous n'utilisez pas le contrôle GeneratedImage, vous devez tout de même enregistrer le tableau d'octets quelque part.
Je comprends vos inquiétudes concernant les grandes sessions. En fonction des détails de vos applications, vous pouvez éviter certaines choses. Toutes les images font-elles référence à un seul utilisateur ou certaines images sont-elles partagées entre les utilisateurs? Les images changent-elles souvent? Si toutes les images appartiennent à un seul utilisateur et changent fréquemment, les enregistrer dans la session est la seule solution. Toutefois, si certains utilisateurs partagent des images ou si les images ne doivent pas changer fréquemment, vous pouvez créer un proxy entre le service Web et l'application Web. Le proxy enregistre les images, soit en mémoire, soit dans une base de données (ou peut-être dans le système de fichiers) et les rend disponibles en tant que ressources via un mappage d'URL. Vous devez définir ce mappage en fonction des éléments internes de vos applications. Cela pourrait être quelque chose comme ça:
http://imageproxy/username/photo123123
Vous devez également créer une URL pour renvoyer le nombre d'images disponibles:
http://imageproxy/username/imagecount
Il ne serait pas nécessaire d'utiliser le composant GeneratedImage. Vous pouvez facilement créer la source HTML de la page en utilisant des balises img standard.
Dans asp.net, vous pouvez écrire et créer une image directement avec l’objet réponse et les principaux navigateurs pourront l’afficher. Mais vous ne pouvez pas transmettre un tableau d'octets, vous devez transmettre un flux de mémoire.
obtenir votre System.Web.HttpContext
Dim ms as New Io.MemoryStream(yourarray)
httpcontext.Response.OutputStream.Write(ms.ToArray,0,ms.Length)
vous mettez cela dans une page display.aspx et si "yourarray" est un tableau d'octets qui représente une image que le navigateur l'affichera.
Vous pouvez ensuite utiliser un contrôle d’image sur n’importe quelle page (même en HTML simple) et définir la source de l’image sur "display.aspx". et votre image apparaîtra.
Maintenant, comme vous avez plusieurs images, vous devrez peut-être créer un contrôle et en créer plusieurs instances, une pour chaque image transmettant le tableau d'octets correspondant.