2009-04-30 54 views
1

我正在调用一个webservice,它以字节数组的形式返回未知数量的图像。 (我不能改变这一点)在页面上动态显示从字节数组派生的图像

我需要在一个aspx网页上显示每个图像。

我目前使用的是Microsoft.Web.GeneratedImage控件; http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16449 显示图像。

我遇到的问题是,由于控件调用一个单独的代码文件来加载图像内容,我使用会话状态来存储bytearray,我不是过分高兴。

下面是我测试项目中的一些代码;

 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 

什么是实现这一目标的最优雅的方式?

任何输入欢迎!

编辑:其他信息;

  • 来自web服务的图像是来自SQL Reporting Services的 。
  • 图像一般会变化 所有时间都在变化(没有真正的 缓存要求)。
  • 图像将是用户特定的。
  • webservice每页仅调用一次。
  • 我从 会话状态的产生 图像后实际处置图像的使用它,因为不会 所需的图像获得 而再次观看。

回答

1

您可以使用data: URI方案将图像数据直接嵌入到页面源中。 Here's the Wikipedia description。这不适用于8之前的IE版本,这可能会导致您的情况无法接受。

+0

哦,IE <8的问题没有打扰我。 – GordonB 2009-05-15 07:27:52

+0

工作很好.... IE唯一的问题是数据uri的大小限制。 Convert.ToBase64String(imageToDisplay).Length <32768 etc等 – GordonB 2009-05-15 09:56:51

2

我想你只想每页请求调用一次你的web服务。实际上,以某种方式缓存字节数组会很好,这样在用户暂时离开页面然后又回来的情况下,Web服务不会再被调用。在这种情况下,在会话中保存字节数组是不可避免的。如果你没有使用GeneratedImage控件,你仍然需要将字节数组保存在某个地方。

我了解您对大型会议的担忧。根据你的应用程序的细节,你可以做一些事情来避免它。所有图像是指单个用户还是一些图像在用户之间共享?图像经常变化吗?如果所有图像属于单个用户并经常更改,则将其保存在会话中是唯一的解决方案。但是,如果有些用户共享图像或图像预计不会频繁更改,则可以在Web服务和Web应用程序之间创建代理。代理会将图像保存在内存或数据库(或者文件系统)中,并通过URL映射将它们作为资源提供。您需要根据应用程序的内部定义此映射。这可能是这样的:

http://imageproxy/username/photo123123 

您还需要创建一个URL返回可用图像的数量:

http://imageproxy/username/imagecount 

将没有必要使用GeneratedImage组件。您可以使用标准img标签轻松构建页面的html源代码。

+0

来自web服务的图像来自SQL Reporting Services。图像通常会一直在变化。图像将是用户特定的。 网页服务每页仅调用一次。缓存可能是一个好主意,我可能会在很短的时间内使用web.caching。 我实际上是在生成的图像使用它之后从会话状态中处理图像,因为希望不需要再次查看图像。 – GordonB 2009-05-14 08:09:14

0

在asp.net中,您可以直接使用响应对象编写图像,并且主要的浏览器将能够显示它。但是你不能传递一个字节数组,你需要传递一个内存流。

让你System.Web.HttpContext

Dim ms as New Io.MemoryStream(yourarray) 
httpcontext.Response.OutputStream.Write(ms.ToArray,0,ms.Length) 

你把在display.aspx页,如果“yourarray”是代表一个图像浏览器将显示它的字节数组。

然后,您可以在任何页面上使用图像控件(甚至是纯HTML),并将图像源设置为“display.aspx”,您的图像将显示出来。

现在,由于您有多个图像,您可能需要创建一个控件并为其创建多个实例,每个图像传递一个对应的字节数组。

相关问题