sexta-feira, 20 de julho de 2007

Callbacks in a custom Controls

Callbacks

Callbacks allow a control or page to perform an out-of-band call back to the server in a manner that does not require the page to be posted back entirely. This means that your custom control does not cause the client browser to wait on an entire page post back and your custom control can enable rich UI functionality. You can develop a custom control that easily combines for example, web resources with client script management to make use of the call back infrastructure. To enable a call back you will:
  • Create a server-side call back event with a given signature in your custom control, (ICallbackEventHandler.PrepareCallbackEvent) that acts on an argument passed into the method<. You should call on a method that developers can override if they extend your custom control;
  • Create a server-side method that generates the result for the call back, ICallbackEventHandler.RenderCallbackResult. You should call a method that developers can override if they extenf your control. The return result will be passed to client-side script defined by your custom control;
  • Create client-side script that manages the return call or error. This will be generated through your custom control;
  • Use the callback event reference hooked up to a client-side event in your custom control.

  

public class CustomControl : CompositeControl
void ICallbackEventHandler.PrepareCallbackEvent(string
eventArgument)
{
PrepareCallBackEvent(eventArgument);
}

String ICallbackEventHandler.RenderCallbackResult()
{
return RenderCallbackResult();
}

private String _callbackEventArg;

// Do work in a protected virtual methods so that derived controls can override
protected virtual void PrepareCallBackEvent(string eventArgument)
{
_callbackEventArg = eventArgument;
}

protected virtual String RenderCallbackResult()
{
if (_callbackEventArg == "theArg")
return = "Some data";
return "Only theArg allowed!";
}

// Additional implementation

// Client script functions that handle the callback
private String sButtonCallBack = "function ButtonCallBack(result, context) { alert(result); }";
private String sButtonCallBackError = "function ButtonErrorCallBack(result, context) { alert(result); }";

protected override void OnInit(EventArgs e)
{
base.OnInit(e);

// Additional implementation

Page.ClientScript.RegisterClientScriptBlock(typeof(CustomControl),
"ButtonCallBack", sButtonCallBack, true);
Page.ClientScript.RegisterClientScriptBlock(typeof(CustomControl),
"ButtonCallBackError", sButtonCallBackError, true);
}

// Additional implementation

protected override void OnPreRender(EventArgs e) {
// Set up the OnClick event to fire an out-of band call to the handler
Attributes["OnClick"] = Page.ClientScript.GetCallbackEventReference(this,
"'theArg'", "ButtonCallback", "null", "ButtonErrorCallback", true);
base.OnPreRender(e);
}
}

Implementando Callbacks cliente sem Postbacks em páginas da Web


No modelo padrão para páginas da Web do ASP.NET, o usuário interage com uma página e clica em um botão ou executa alguma outra ação que resulta em um novo postback. A página e seus controles são recriados, o código de página é executado no servidor, e uma nova versão da página é processada para o navegador. Entretanto, em algumas situações, é útil executar código de servidor a partir do cliente sem executar um novo postback. Se o script cliente na página estiver mantendo algumas informações de estado (por exemplo, valores de variáveis locais), postar a página e obter uma nova cópia dela destrói esse estado. Além disso, postbacks de página introduzem sobrecarga de processamento que pode diminuir o desempenho e forçar o usuário a aguardar a página ser processada e recriada.


Para evitar a perda do estado do cliente e não gerar a sobrecarga do processamento de uma resposta do servidor, você pode codificar uma página da Web do ASP.NET para que ele possa fazer chamadas de retorno cliente. Em uma chamada de retorno cliente, uma função script cliente envia uma solicitação para uma página da Web do ASP.NET. A página da Web executa uma versão modificada do seu ciclo normal de vida — a página é iniciada e seus controles e outros membros são criados, e então um método especialmente marcado é chamado. O método executa o processamento que você codificou e então retorna um valor para o navegador que pode ser lido por outra função script cliente. Em todo esse processo, a página está ativa no navegador.

Vários controles do servidor Web utilizam chamadas de retorno cliente. Por exemplo, o controle TreeView utiliza chamadas de retorno cliente para implementar sua funcionalidade de preenchimento por demanda. Para obter mais informações consulte Visão geral sobre controle TreeView do Servidor Web.

Componentes de Chamadas de Retorno Cliente

Criar uma página ASP.NET que implementa chamadas de retorno é similar à criar qualquer página ASP.NET, com pequenas diferenças. O código do servidor da página deve:

  • Implementar a interface ICallbackEventHandler. Você pode adicionar essa declaração de interface para qualquer página da Web do ASP.NET.

  • Um método que implementa a interface RaiseCallbackEvent. Esse método será chamado para executar a chamada de retorno a partir do servidor.

Além disso, a página pode conter três funções script cliente que executam as seguintes ações:

  • Uma função chama um método auxiliar que realiza a solicitação real para o servidor. Nessa função, você pode executar lógica personalizada para preparar os argumentos do evento primeiro, em seguida, você pode enviar uma seqüência de caracteres como um parâmetro para o manipulador de eventos de chamada de retorno do lado do servidor.

  • Outra função recebe (é chamado por) o resultado do código do servidor que processou o evento de chamada de retorno, aceitando uma seqüência de caracteres que representa os resultados. Ela é chamada de função de chamada de retorno cliente.

  • Uma terceira função é a função auxiliar que realiza a solicitação real para o servidor, a qual é gerada automaticamente pelo ASP.NET quando você gera uma referência a essa função utilizando o método GetCallbackEventReference no código do servidor.

Ambos, chamadas de retorno e postbacks, são solicitações para a página de origem, assim, chamadas de retorno cliente e postbacks são armazenados em logs de servidores Web como uma solicitação de página.

Implementando a Interface Apropriada no Código do Servidor

Para executar com êxito o código do servidor a partir do cliente sem executar um postback, você deve implementar as interfaces apropriadas no código do servidor.

Declarando a interface ICallbackEventHandler

Você pode declarar a interface ICallbackEventHandler como parte da declaração de classe para a página. Se você estiver criando uma página code-behind, você pode declarar a interface utilizando sintaxe como demonstrado a seguir.

Visual Basic
Partial Class CallBack_DB_aspx
Inherits System.Web.UI.Page
Implements System.Web.UI.ICallbackEventHandler
C#
public partial class CallBack_DB_aspx : 
System.Web.UI.Page, System.Web.UI.ICallbackEventHandler

Se você estiver trabalhando em uma página de um único arquivo ou controle de usuário, você pode adicionar a declaração utilizando uma diretiva @ Implements na página, como nos exemplos de código a seguir:

Visual Basic
<%@ Page Language="VB" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
C#
<%@ Page Language="C#" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
NoteObservação

O nome interface diferencia maiúsculas de minúsculas.

Criando um Método Callback de Servidor

No código do servidor, você deve criar um método que implementa o método RaiseCallbackEvent e um método que implementa o método GetCallbackResult. O método RaiseCallbackEvent aceita uma única seqüência de caracteres como argumento, em vez dos dois argumentos que são normalmente utilizados com manipuladores de eventos normal. Uma parte do método pode parecer com o exemplo de código a seguir.

Visual Basic
Public Sub RaiseCallbackEvent(ByVal eventArgument As String) _
Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
Return eventArgument & " new value"
End Sub
C#
public void RaiseCallbackEvent(String eventArgument)
{
return eventArgument + " new value";
}

O método GetCallbackResult não recebe argumentos e retorna uma seqüência de caracteres. Uma parte do método pode parecer com o exemplo de código a seguir.

Visual Basic
Public Function GetCallbackResult() As String Implements _
System.Web.UI.ICallbackEventHandler.GetCallbackResult
Return aStringValue
End Function
C#
public string GetCallbackResult()
{
return aStringValue;
}

Criando Funções Scripts Cliente

Você deve adicionar funções script cliente à página para executar duas funções: enviar a chamada de retorno para a página do servidor e receber os resultados. As duas funções script cliente são gravadas no ECMAScript (JavaScript).

Enviando a Chamada de Retorno

A função para enviar a chamada de retorno é gerada no código do servidor. A chamada de retorno real é executada por uma função de biblioteca que está disponível para qualquer página que implementa a interface ICallbackEventHandler. Você pode obter uma referência para a função de biblioteca chamando o método GetCallbackEventReference da página, que pode ser acessado através da propriedade ClientScript da página. Você então compila uma função cliente dinamicamente que inclui uma chamada para o valor de retorno do método GetCallbackEventReference. Você passa para esse método uma referência para a página (this no C# ou Me no Visual Basic), o nome do argumento pelo qual você irá passar dados, o nome da função script cliente que receberá os dados da chamada de retorno, e um argumento que passa qualquer contexto que você desejar.

Quando você tiver compilado a função, você a insere dentro da página através da chamada do método RegisterClientScriptBlock.

O exemplo de código a seguir mostra como criar dinamicamente uma função denominada CallServer que chama a chamada de retorno.

Visual Basic
Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
Dim cm As ClientScriptManager = Page.ClientScript
Dim cbReference As String
cbReference = cm.GetCallbackEventReference(Me, "arg", "ReceiveServerData", "")
Dim callbackScript As String = ""
callbackScript &= "function CallServer(arg, context)" & "{" & cbReference & "; }"
cm.RegisterClientScriptBlock(Me.GetType(), "CallServer", callbackScript, True)
End Sub
C#
void Page_Load(object sender, EventArgs e)
{
ClientScriptManager cm = Page.ClientScript;
String cbReference = cm.GetCallbackEventReference(this, "arg", "ReceiveServerData", "");
String callbackScript = "function CallServer(arg, context) {" + cbReference + "; }";
cm.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);
}

Os nomes dos argumentos que são aceitos pela função que você está gerando devem corresponder aos nomes dos valores que você passa para o método GetCallbackEventReference.

O exemplo de código a seguir mostra algumas marcações que podem ser utilizadas para chamar a chamada de retorno e processar seu valor de retorno:

Visual Basic
<input type="button" value="Callback" 
onclick="CallServer(1, alert('Callback'))"/>
<br />
<span id="Message"></span>
C#
<input type="button" value="Callback" 
onclick="CallServer(1, alert('Callback'))"/>
<br />
<span id="Message"></span>

Recebendo a Chamada de Retorno

Você pode escrever a função cliente que recebe chamadas de retorno estaticamente na página. A função deve ser nomeada de modo a corresponder ao nome que você passa na chamada para o método GetCallbackEventReference. A função receptora aceita dois valores de seqüência de caracteres: um para o valor de retorno e um segundo valor, opcional, para o valor de contexto que é passado de volta através do servidor.


A função pode ser semelhante ao exemplo de código a seguir:

<script type="text/javascript">
function ReceiveServerData(arg, context)
{
Message.innerText = 'Processed callback.';
}
</script>


sexta-feira, 13 de julho de 2007

Tipos de arquivo no .NET


Aplicativos de site da Web podem conter uma variedade de tipos de arquivo, alguns suportados e gerenciados pelo ASP.NET, e outros suportados e gerenciados pelo servidor IIS.

A maioria dos tipos de arquivo do ASP.NET pode ser gerada automaticamente usando o item de menu Add New Item no Visual Developer da Web.

Tipos de arquivo são mapeados para aplicativos usando mapeamentos de aplicativo. Por exemplo, se você abrir um arquivo com a extensão .txt, o aplicativo bloco de notas será aberto, provavelmente porque os tipos de arquivo .txt são mapeados por padrão para notepad.exe.

Tipos de arquivo gerenciados pelo ASP.NET

Os tipos de arquivo que são gerenciados pelo ASP.NET são mapeados para o Aspnet_isapi.dll no IIS.

Tipo de arquivo Local Descrição

.asax

Raiz de aplicativo.

Normalmente um arquivo Global.asax que contém código que deriva da classe HttpApplication e representa o aplicativo.

Para obter mais informações, consulte Sintaxe Global.asax.

.ascx

Raiz do aplicativo ou uma subpasta.

Um arquivo de controle de usuário da Web que define um controle de usuário personalizado, reutilizável.

Para obter mais informações, consulte Controles de usuário ASP.NET.

.ashx

Raiz de aplicativo ou uma subpasta.

Um arquivo manipulador genérico que contém código que implementa a interface IHttpHandler para manipular todas as solicitações recebidas.

Para obter mais informações, consulte Introdução aos manipuladores HTTP.

.asmx

Raiz de aplicativo ou uma subpasta.

Um arquivo de XML Web Services que contém as classes e métodos que estarão disponíveis para outros aplicativos da Web por meio de SOAP.

Para obter mais informações, consulte XML Web Services Publishing and Deployment.

.aspx

Raiz de aplicativo ou uma subpasta.

Um arquivo de formulários da Web ASP.NET que pode conter controles da Web e lógica corporativa.

Para obter mais informações, consulte Páginas da Web ASP.NET e Controles de servidores Web do ASP.NET.

.axd

Raiz de aplicativo.

Um arquivo trace-viewer, normalmente Trace.axd.

Para obter mais informações, consulte Rastreamento no ASP.NET.

.browser

Subdiretório App_Browsers.

Um arquivo de definição de navegador usado para identificar os recursos ativados do navegador do cliente.

Para obter mais informações, consulte Controles de Servidor Web do ASP.NET e Recursos do Navegador.

.cd

Raiz de aplicativo ou uma subpasta.

Um arquivo de diagrama de classe.

Para obter mais informações, consulte Trabalhando com diagramas de classe.

.compile

subpasta Bin.

Um arquivo pré-compilado que aponta para o assembly apropriado. Tipos de arquivo executáveis (.aspx, .ascx,. master, arquivos de tema) são pré-compilados e colocados no subdiretório Bin.

Para obter mais informações, consulte Visão geral da Pré-compilação do Site da Web ASP.NET.

.config

Raiz de aplicativo ou uma subpasta.

Normalmente um arquivo de configuração Web.config que contém elementos XML cujas definições configuraram os vários recursos do ASP.NET.

Para obter mais informações, consulte Arquivos de configuração ASP.NET.

.cs, .jsl, .vb

Subpasta App_Code, ou no caso de um arquivo de code-behind para uma página ASP.NET, no mesmo diretório que a página da Web.

Arquivo de código-fonte de classe que é compilada em tempo de execução. A classe pode ser um HTTP Module, um HTTP Handler, ou um arquivo de code-behind para uma página Introdução aos manipuladores HTTP ASP.NET.

.csproj, .vbproj, vjsproj

Diretório de projeto Visual Studio.

Um arquivo de projeto de um aplicativo cliente Visual Studio.

Para obter mais informações, consulte Projects and Solutions.

.disco, .vsdisco

Subdiretório App_WebReferences.

Um arquivo de descoberta de XML Web Services usado para ajudar a localizar serviços da Web disponíveis.

Para obter mais informações, consulte XML Web Services Publishing and Deployment.

.dsdgm, .dsprototype

Raiz de aplicativo ou uma subpasta.

Um arquivo de diagrama de serviço distribuído (DSD, distributed service diagram) que pode ser adicionado a qualquer solução do Visual Studio que forneça ou consuma serviços da Web para fazer engenharia reversa da arquitetura de interações do serviço da Web.

Para obter mais informações, consulte XML Web Services Publishing and Deployment.

.dll

subpasta Bin.

Um arquivo de biblioteca de classes compilado. Como alternativa, você pode colocar o código-fonte das classes no subdiretório App_Code.

Para obter mais informações, consulte Pastas de Código Compartilhadas em Sites Web do ASP.NET.

.licx, .webinfo

Raiz de aplicativo ou uma subpasta.

Um arquivo de licença. O licenciamento permite a autores de controles ajudar a proteger propriedade intelectual, verificando se um usuário está autorizado a utilizar o controle.

Para obter mais informações, consulte HOW TO: Componentes licença e controles.

.master

Raiz de aplicativo ou subdiretório.

Uma página mestre que define o layout para outras páginas da Web no aplicativo que fazem referência ao mestre.

Para obter mais informações, consulte Páginas Mestras do ASP.NET.

.mdb, .ldb

Subdiretório App_Data.

Um arquivo de banco de dados Access.

Para obter mais informações, consulte Acessando dados com o ASP.NET.

.mdf

Subdiretório App_Data.

Arquivo de banco de dados SQL.

Para obter mais informações, consulte Acessando dados com o ASP.NET.

.msgx, .svc

Raiz de aplicativo ou uma subpasta.

Um arquivo do serviço Indigo Framework Messaging (MFx).

.rem

Raiz de aplicativo ou uma subpasta.

Um arquivo manipulador de remoting.

Para obter mais informações, consulte SOAP Message Modification Using SOAP Extensions.

.resources

Subdiretório App_GlobalResources ou App_LocalResources.

Um arquivo de recurso que contém strings que se referem a imagens, textos localizáveis, ou outros dados.

Para obter mais informações, consulte Resources in Applications ou Como: Criar Arquivos de Recursos para Sites da Web do ASP.NET.

.resx

Subdiretório App_GlobalResources ou App_LocalResources.

Um arquivo de recursos que contém strings que se referem a imagens, textos localizáveis, ou outros dados.

Para obter mais informações, consulte Resources in Applications ou Como: Criar Arquivos de Recursos para Sites da Web do ASP.NET.

.sdm, .sdmDocument

Raiz de aplicativo ou uma subpasta.

Um arquivo de modelo de definição de sistema (SDM, system definition model).

Para obter mais informações, consulte Visão geral sobre o modelo de definição do sistema (SDM).

.sitemap

Raiz de aplicativo.

Um arquivo de mapa de site que contém a estrutura do site da Web. O ASP.NET vem com um provedor de mapa de site padrão que usa arquivos de mapa de site para facilmente exibir um controle de navegação em uma página da Web.

Para obter mais informações, consulte Navegação site ASP.NET.

.skin

Subdiretório App_Themes.

Um arquivo de skin usado para determinar formatação de exibição.

Para obter mais informações, consulte Temas e Aparências do ASP.NET.

.sln

Diretório de projeto do Visual Web Developer.

Um arquivo de solução para um projeto Visual Web Developer.

Para obter mais informações, consulte Projects and Solutions.

.soap

Raiz de aplicativo ou uma subpasta.

Um arquivo de extensão SOAP.

Para obter mais informações, consulte SOAP Message Modification Using SOAP Extensions.




quinta-feira, 12 de julho de 2007

Armazenando imagens na base de dados e exibí-la em GridView


Introduzindo imagens na base de dados e indicá-la em GridView com Handler.ashx


Introdução
Este artigo explica o método de introduzir imagens na base de dados do usuário do SQL e exibí-la em um controle do ASP.NET GridView com a ajuda de Handler.aspx.

Descrição
Você viu alguma aplicação ou Web Site sem imagens? Não, você não viu. As imagens desempenham um papel principal no desenvolvimento da aplicação da internet. Ou é um web site de HTML estático ou uma aplicação avançada de RAD, tudo é construído junto com imagens. Se sua aplicação for um site de comércio eletrônico ou portal da galeria de imagens, definitivamente você tem que sofrer para guardar as imagens em lugares diferentes com tamanhos e tipos diferentes. E não é um trabalho o fácil controlar aquelas imagens não desejadas e antigas a serem removidas da pasta de imagens. Assim o seu tempo e esforço é claramente consumindo.

Para fazer sua tarefa mais fácil, este artigo explica os métodos para armazenar as imagens no banco de dados. Há muitas vantagens de conservar as imagens na base de dados. A vantagem principal é gerência fácil das imagens. Você pode controlar o número e o tamanho das imagens armazenadas em sua base. Você pode remover todas as imagens desnecessárias da base de dados em um único comando sql e você pode fazer o backup das imagens facilmente.

Introduzindo a imagem na base de dados

Para começar, deixe-me explicar a estrutura da tabela da base de dados que vamos usar para introduzir a imagem. A tabela que você criará para armazenar a imagem deve conter uma coluna do tipo de dados IMAGE. Este tipo de dados de imagem é de dados binários Variable-length com um comprimento máximo de 2^31 - (2.147.483.647) bytes 1. Para armazenar a imagem nesta coluna nós a converteremos em um array binário com a ajuda de algumas classes do namespace IO para então introduzí-la na tabela. Para demonstração, nós vamos criar uma tabela com nome ImageGallery com as quatro colunas na seguinte estrutura:

Nome da coluna Descrição Tipo de dados
Img_Id Coluna da identidade para a identificação da imagem uniqueidentifier
Image_Content Armazenar a imagem no formato binário image
Image_Type Armazenar o formato da imagem (i.e. JPEG, GIF, PNG, etc.) varchar
Image_Size Armazenar o tamanho da imagem bigint

Depois que nós criamos a tabela na base de dados, nós podemos começar a parte de codificação.

1. Abra sua aplicação web no Visual Studio 2005, arraste um controle do Upload da arquivo e um controle da Botão na Web page.
2. No code-behind adicione o namespace System.IO.

using System.IO;

3. No evento de Button1_Click do botão, escrever o seguinte código:
if (FileUpload1.PostedFile != null && FileUpload1.PostedFile.FileName != "")
{
byte[] myimage = new byte[FileUpload1.PostedFile.ContentLength];
HttpPostedFile Image = FileUpload1.PostedFile;
Image.InputStream.Read(myimage, 0, (int)FileUpload1.PostedFile.ContentLength);


SqlConnection myConnection = new SqlConnection(“Your Connection String”);
SqlCommand storeimage = new SqlCommand("INSERT INTO ImageGallery " +"(Image_Content, Image_Type, Image_Size) " +" values (@image, @imagetype, @imagesize)", myConnection);
storeimage.Parameters.Add("@image", SqlDbType.Image, myimage.Length).Value = myimage;
storeimage.Parameters.Add("@imagetype", SqlDbType.VarChar, 100).Value = FileUpload1.PostedFile.ContentType;
storeimage.Parameters.Add("@imagesize", SqlDbType.BigInt, 99999).Value = FileUpload1.PostedFile.ContentLength;

myConnection.Open();
storeimage.ExecuteNonQuery();
myConnection.Close();
}

Para fazer o upload da imagem de qualquer local (seu HD) para o servidor, nós temos que usar o objeto de HttpPostedFile. Apontar para o arquivo enviado ao objeto de HttpPostedFile. Então o método de InputStream.Read lerá o conteúdo da imagem por uma seqüência dos bytes do Stream. Assim o myimage conterá a imagem como dados binários. Agora nós temos que passar estes dados no objeto de SqlCommand, que os introduzirá na tabela da base de dados.

Exibindo a imagem em um GridView com Handler.ashx

Até agora, o artigo explicou como introduzir imagens na base de dados. A imagem está na base de dados no formato de dados binário. Recuperar estes dados em um Web page de ASP.NET é razoavelmente fácil, mas exibí-lo não é tão simples. O problema básico é que para mostrar uma imagem em uma página aspx, você precisa adicionar um Tag da imagem que fará ligação a um arquivo de imagem através do atributo src ou você precisará pôr um controle da imagem em sua página e especificar a propriedade ImageUrl.

Por exemplo:
<asp:image Runat="server" ImageUrl="YourImageFilePath" ID="Image1" />

Infelizmente, esta solução não funcionará se você necessitar mostrar dinâmicamente dados da imagem. Embora você possa ajustar o atributo de ImageUrl no código, você não tem nenhuma maneira ajustar programmatically o conteúdo da imagem. Você poderia primeiramente gravar os dados do arquivo da imagem no HD do web server, mas essa solução seria dramaticamente mais lenta, desperdiçaria espaço, e levanta a possibilidade de erros da concorrência se os pedidos múltiplos estivessem servidos ao mesmo tempo e todos tentassem escrever o mesmo arquivo.

Nestas situações, a solução é usar um recurso separado de ASP.NET que retorne os dados binários diretamente da base de dados. Aqui a classe HTTP Handler vai nos ajudar.

O que é um Handler?

O ASP.NET HTTP Handler é uma classe simples que permita que você processe um pedido e retorne uma resposta ao browser. Simplesmente nós podemos dizer que um handler é responsável para cumprir pedidos do browser. Pode processar somente um pedido de cada vez, o que gera por sua vez o desempenho elevado. A classe handler implementa a interface IHttpHandler.

Para esta demonstração do artigo, nós exibiremos a imagem no controle GridView junto com os dados que nós armazenamos na tabela. Estão aqui as etapas requeridas para realizar isto:

1. Criar um arquivo Handler.ashx para executar a recuperação da imagem. Esta página de Handler.ashx conterá somente um método chamado ProcessRequest. Este método retornará dados binários ao pedido entrante. Neste método, nós faremos o processo normal e o retorno da recuperação de dados somente o campo de Image_Content como bytes do array.

Código de exemplo abaixo:
public void ProcessRequest (HttpContext context)
{
SqlConnection myConnection = new SqlConnection(“YourConnectionString”);
myConnection.Open();
string sql = "Select Image_Content from ImageGallery where Img_Id=@ImageId";
SqlCommand cmd = new SqlCommand(sql, myConnection);
cmd.Parameters.Add("@ImageId", SqlDbType.Int).Value = context.Request.QueryString["id"];
cmd.Prepare();
SqlDataReader dr = cmd.ExecuteReader();
dr.Read();
context.Response.ContentType = dr["Image_Type"].ToString();
context.Response.BinaryWrite((byte[])dr["Image_Content"]);
}

2. Colocar um controle GridView na página do aspx, com a uma coluna TemplateField, adicionar um controle de imagem na seção de ItemTemplate do TemplateField. Especificar a propriedade de ImageUrl como:
<asp:TemplateField>
<ItemTemplate>
<asp:Image ID="Image1" runat="server" ImageUrl='<%# "Handler.ashx?id=" + Eval("Img_Id") %>' />
</ItemTemplate>
</asp:TemplateField>
3. Agora nós podemos ligar o controle de GridView para exibir todos os registros na tabela:
GridView1.DataSource = FetchAllImagesInfo();
GridView1.DataBind ();

Antes que você ligue o GridView, você deve escrever o método de FetchAllImagesInfo para retornar todos os registros com os dados da imagem da tabela e então você tem que carregar as imagens no controle de GridView. Apenas isto. Quando você rodar seu projeto, você verá as imagens sendo carregadas no controle GridView.

public DataTable FetchAllImagesInfo())
{
string sql = "Select * from ImageGallery";
SqlDataAdapter da = new SqlDataAdapter(sql, "Your Connection String");
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}

Esta é uma explanação muito simples sobre armazenar imagens na base de dados e para recuperá-las afim de exibí-las na Web page.

Para ver nossa aplicação de amostra, clique aqui.

Neobux