Pergunta

Eu estou chamando um webservice que está retornando uma quantidade desconhecida de imagens na forma de uma coleção de matrizes de bytes. (Eu não posso mudar isso)

Eu preciso para exibir cada imagem em uma única página aspx.

Atualmente estou usando o controle Microsoft.Web.GeneratedImage; http://www.codeplex.com/aspnet/Release/ProjectReleases. aspx? ReleaseId = 16449 para exibir as imagens.

O problema que tenho é que, desde o controle chama um arquivo de código separado para carregar o conteúdo da imagem, eu estou usando o estado da sessão para armazenar o bytearray, que eu não sou demasiado feliz.

Aqui está algum código do meu projeto de teste;

     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

O que é a maneira mais elegante de conseguir isso?

Qualquer entrada de boas-vindas !!!

EDIT: Informações adicionais;

  • As imagens do webservice são vindo do SQL Reporting Services.
  • As imagens geralmente seria mudando o tempo todo (não real exigência de caching).
  • Imagens seria específico de usuário.
  • O webservice é chamado apenas uma vez por página.
  • Na verdade, estou a eliminação da imagem da o estado da sessão após o gerado imagem usa-lo, como a imagem não será necessário para ser visto novamente por um enquanto.
Foi útil?

Solução

Você pode incorporar os dados da imagem diretamente no código fonte da página usando o esquema URI data:. Aqui está a descrição Wikipedia . Isso não funciona com versões do IE anteriores a 8, porém, o que pode torná-lo inaceitável para a sua situação.

Outras dicas

Eu suponho que você quer chamar o serviço web apenas uma vez por solicitação de página. Na verdade, seria bom para alguma forma armazenar em cache a matriz de bytes, para que o serviço web não é chamado novamente no caso do usuário momentaneamente se move para fora da página e depois volta. Nesse caso salvar o array de bytes na sessão é inevitável. Se você não usar o controle GeneratedImage, você ainda precisa para salvar a algum lugar matriz de bytes.

Eu entendo suas preocupações em relação a sessões grandes. Com base nos detalhes de suas aplicações, existem algumas coisas que você pode fazer para evitá-lo. São todas as imagens se referem a um único usuário, ou estão algumas imagens compartilhadas entre os usuários? Será que as imagens mudam frequentemente? Se todas as imagens pertencem a um único usuário e mudam com freqüência, em seguida, salvá-los na sessão é a única solução. Se, no entanto alguns usuários compartilhar imagens ou as imagens não se espera que mudam frequentemente, então você pode criar um proxy entre o serviço web ea aplicação web. O proxy irá salvar as imagens, seja na memória ou em um banco de dados (ou talvez no sistema de arquivos) e irá disponibilizá-los como recursos, através de um mapeamento de URL. Você precisará definir esse mapeamento, baseado nas partes internas de suas aplicações. Poderia ser algo como isto:

http://imageproxy/username/photo123123

Você também precisa criar um URL para retornar o número de imagens disponíveis:

http://imageproxy/username/imagecount

Não haveria necessidade de usar o componente GeneratedImage. Você poderia facilmente construir o código HTML da página usando tags img padrão.

No asp.net, você pode escrever e imagem diretamente com o objeto de resposta e os principais navegadores será capaz de exibi-lo. Mas você não pode passar um array de bytes, você precisa passar um fluxo de memória.

obter o seu System.Web.HttpContext

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

você colocar isso em uma página display.aspx e se "yourarray" é um array de bytes que representa uma imagem o navegador irá exibi-lo.

Você pode usar, em seguida, um controle de imagem em qualquer página (mesmo html simples) e definir a fonte de imagem para "display.aspx" e sua imagem vai aparecer.

Agora, desde que você tem várias imagens, pode ser necessário criar um controle e criar várias instâncias do mesmo, um para cada imagem passando a matriz byte correspondente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top