I'm calling a webservice that is returning an unknown quantity of images in the form of an a collection of byte arrays. (I can't change this)
I need to display each image on a single aspx webpage.
I'm currently using the Microsoft.Web.GeneratedImage control; http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16449 to display the images.
The issue i have is that since the control calls a seperate code file to load the image content, i am using session state to store the bytearray, which i'm not overly happy about.
Here's some code from my test project;
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
What's the most elegant way of achieving this?
Any input welcome!!!
EDIT: Additional info;
I suppose that you want to call your web service only once per page request. In fact, it would be good to somehow cache the byte array, so that the web service isn't called again in the case the user momentarily moves away from the page and then comes back. In that case saving the byte array in the session is inevitable. If you didn't use GeneratedImage control, you would still need to save the byte array somewhere.
I understand your worries regarding big sessions. Based on the details of your applications, there are some things you could do to avoid it. Are all images refer to a single user, or are some images shared among users? Do the images change often? If all the images belong to a single user and change frequently, then saving them in the session is the only solution. If however some users share images or the images aren't expected to frequently change, then you could create a proxy between the web service and the web application. The proxy will save the images, either in memory or in a database (or perhaps in the file system) and will make them available as resources, through a URL mapping. You would need to define this mapping, based on the internals of your applications. It could be something like this:
http://imageproxy/username/photo123123
You also need to create a URL to return the number of available images:
http://imageproxy/username/imagecount
There would be no need to use the GeneratedImage component. You could easily build the html source of the page using standard img tags.