Pregunta

Llamo a un servicio web que devuelve una cantidad desconocida de imágenes en forma de una colección de conjuntos de bytes. (No puedo cambiar esto)

Necesito mostrar cada imagen en una sola página web de aspx.

Actualmente estoy usando el control Microsoft.Web.GeneratedImage; http://www.codeplex.com/aspnet/Release/ProjectReleases. aspx? ReleaseId = 16449 para mostrar las imágenes.

El problema que tengo es que, dado que el control llama a un archivo de código separado para cargar el contenido de la imagen, estoy usando el estado de sesión para almacenar el bytearray, del cual no estoy muy contento.

Aquí hay algo de código de mi proyecto de prueba;

     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

¿Cuál es la forma más elegante de lograr esto?

Cualquier entrada de bienvenida!

EDITAR: Información adicional;

  • Las imágenes del servicio web son procedente de SQL Reporting Services.
  • Las imágenes generalmente serían Cambiando todo el tiempo (no real requisito de almacenamiento en caché).
  • Las imágenes serían específicas del usuario.
  • El servicio web solo se llama una vez por página.
  • En realidad estoy eliminando la imagen de estado de la sesión después de la generada La imagen la usa, ya que la imagen no será necesitaba ser visto de nuevo para una mientras.
¿Fue útil?

Solución

Puede incrustar los datos de la imagen directamente en el origen de la página utilizando el esquema de URI data: . Aquí está la descripción de Wikipedia . Sin embargo, eso no funciona con las versiones de IE anteriores a la 8, lo que puede hacer que sea inaceptable para su situación.

Otros consejos

Supongo que desea llamar a su servicio web solo una vez por solicitud de página. De hecho, sería bueno almacenar de alguna manera la matriz de bytes, para que no se vuelva a llamar al servicio web en caso de que el usuario se aleje momentáneamente de la página y luego regrese. En ese caso, guardar la matriz de bytes en la sesión es inevitable. Si no usó el control GeneratedImage, aún tendría que guardar la matriz de bytes en algún lugar.

Entiendo tus preocupaciones con respecto a las sesiones grandes. Según los detalles de sus aplicaciones, hay algunas cosas que puede hacer para evitarlo. ¿Todas las imágenes se refieren a un solo usuario o se comparten algunas imágenes entre los usuarios? ¿Cambian las imágenes a menudo? Si todas las imágenes pertenecen a un solo usuario y cambian con frecuencia, guardarlas en la sesión es la única solución. Sin embargo, si algunos usuarios comparten imágenes o no se espera que las imágenes cambien con frecuencia, puede crear un proxy entre el servicio web y la aplicación web. El proxy guardará las imágenes, ya sea en la memoria o en una base de datos (o tal vez en el sistema de archivos) y las pondrá a disposición como recursos, a través de una asignación de URL. Necesitaría definir este mapeo, basado en las partes internas de sus aplicaciones. Podría ser algo como esto:

http://imageproxy/username/photo123123

También debe crear una URL para devolver el número de imágenes disponibles:

http://imageproxy/username/imagecount

No habría necesidad de usar el componente GeneratedImage. Puede crear fácilmente la fuente html de la página utilizando etiquetas img estándar.

En asp.net puede escribir e imágenes directamente con el objeto de respuesta y los principales navegadores podrán mostrarlo. Pero no puede pasar una matriz de bytes, debe pasar una secuencia de memoria.

obtenga su System.Web.HttpContext

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

lo colocas en una página display.aspx y si " yourarray " es una matriz de bytes que representa una imagen que el navegador la mostrará.

Puede usar un control de imagen en cualquier página (incluso en el HTML simple) y configurar la fuente de la imagen en " display.aspx " y tu imagen aparecerá.

Ahora, ya que tiene varias imágenes, es posible que deba crear un control y crear varias instancias del mismo, una para cada imagen que pase la matriz de bytes correspondiente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top