ASP .NET - Usando um manipulador (Handle) ASHX
Em ocasiões onde suas páginas desejam retornar uma imagem, uma string ou outras páginas não HTML a utilização de um manipulador ASHX pode ser uma solução que lhe dará um ganho de desempenho.Como exemplo cenários onde de utilização de um manipulador ASHX pode ser conveniente citamos:
<img
alt="ícone customizado" src="Icon.ashx?usuario=bob"></img>
Neste artigo eu vou mostrar como podemos usar um manipulador ASHX em um desses cenários. Para isso eu vou usar o Visual Web Developer 2010 Express Edition.
O nosso objetivo será criar uma página para retornar um conteúdo XML ou uma imagem para o visitante. Um objetivo bem simples...
Uma solução trivial para retornar um conteúdo XML seria criar uma página ASPX e no evento Load da página usar o método Response.Write para retornar o XML.
O código abaixo mostra esta solução:
Public Class RSS |
public
class RSS : System.Web.UI.Page { private void Page_Load(object sender, System.EventArgs e) { Response.ContentType = "text/xml"; Response.ContentEncoding = Encoding.UTF8; string sXml = BuildXMLString(); Response.Write( sXml ); Response.End(); } } |
A solução acima vai funcionar e mas não haveria uma solução melhor ?
O problema é que a página acima herda de System.Web.UI.Page e que o manipuladora da página esta preparado para servir páginas aspx (WebForms) e dessa forma inclui uma sobrecarga de recursos não necessários apenas para servir uma simples arquivo XML.
Uma solução alternativa é criar um manipulador ASHX que realiza o mapeamento para o engine ASP .NET e permite realizar a tarefa de forma simples e usando poucos recursos.
Para criar um manipulador ASHX em uma aplicação ASP .NET é muito simples.
Abra o Visual Web Developer 2010 Express e no menu File selecione New Web Site usando o template ASP .NET Web Site e selecione a linguagem Visual Basic ou C# informando o nome DemoAshx ;
Com o projeto aberto no Visual Developer 2010 Express Edition clique no menu Project e selecione Add New Item;
A seguir selecione o template Generic Handler e informe o nome HandlerDemo.ashx selecionando a linguagem Visual Basic ou C# (fica a seu critério);
Feito isso será gerado o arquivo HandlerDemo.ashx com o código gerado automaticamente onde podemos notar o seguinte:
Você não deve modificar a herança nem remover os membros gerados mas alterá-los implementando o código desejado a realizar a sua tarefa conforme veremos logo a seguir;
Obs: É recomendado mapear uma URL antiga ou caminho para o novo arquivo ASHX. Por questão de compatibilidade e por motivo de otimização você pode desejar que o novo manipulador aponte para uma URL antiga no seu site. Para fazer isso você pode usar o mapeamento no arquivo Web.Config conforme abaixo:
<system.web>
<urlMappings enabled="true">
<add url="~/Default.aspx" mappedUrl="~/Handler.ashx"/>
</urlMappings>
.....
Para resolver um dos nossos problema, que é gerar conteúdo XML vamos alterar a classe gerada conforme o código abaixo:
Public Class HandlerDemo Implements IHttpHandler Public Sub ProcessRequest(context As HttpContext) Implements System.Web.IHttpHandler.ProcessRequest context.Response.ContentType = "text/xml" context.Response.ContentEncoding = System.Text.Encoding.UTF8 Dim sXml As String = criarXMLString() context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(600)) context.Response.Cache.SetCacheability(HttpCacheability.[Public]) context.Response.Write(sXml) End Sub Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable Get Return True End Get End Property End Class |
public
class RSSHandler : IHttpHandler { public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/xml"; context.Response.ContentEncoding = System.Text.Encoding.UTF8; string sXml = criarXMLString(); context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(600)); context.Response.Cache.SetCacheability(HttpCacheability.Public); context.Response.Write( sXml ); } public bool IsReusable { get { return true; } } } |
Para resolver o problema de servir uma imagem ao visitante a classe poderia ser alterada para :
Public Class Handler |
public
class Handler : IHttpHandler { public void ProcessRequest (HttpContext context) { context.Response.ContentType = "image/jpg"; context.Response.WriteFile("~/Deserto.jpg"); } public bool IsReusable { get { return false; } } |
Como eu estou com preguiça de criar a rotina
criarXMLString() para gerar o conteúdo XML vou testar somente o segundo caso que é a exibição da imagem.
Executando o web site criado iremos obter:
Podemos incluir mais funcionalidade ao nosso exemplo da imagem, pois tudo o que ele faz e permitir obter uma imagem através de um manipulador ASHX.
Podemos permitir que a imagem seja requisitada através de uma coleção QueryString e você pode usar Request.QueryString no manipulador da mesma maneira que usa em suas páginas ASPX.
Vamos então modificar o código para permitir este recurso:
Public Class Handler Implements IHttpHandler Public Sub ProcessRequest(context As HttpContext) Implements System.Web.IHttpHandler.ProcessRequest Dim r As HttpResponse = context.Response r.ContentType = "image/jpg" Dim file As String = context.Request.QueryString("arq") If file = "jardim" Then r.WriteFile("Jardim.jpg") Else r.WriteFile("Deserto.jpg") End If End Sub Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable Get Return False End Get End Property End Class |
ppublic
class Handler : IHttpHandler { public void ProcessRequest (HttpContext context) { HttpResponse r = context.Response; r.ContentType = "image/jpg"; string file = context.Request.QueryString["arq"]; if (file == "jardim") { r.WriteFile("Jardim.jpg"); } else { r.WriteFile("Deserto.jpg"); } } public bool IsReusable { get { return false; } } } |
O código acima recebe uma requisição e então retorna um arquivo diferente baseado no valor da QueryString.A string retornada pode ser :
URL: http://localhost:59789/DemoAshx/HandlerDemo.ashx?arq=jardim Arquivo query string: jardim arquivo exibido: Jardim.jpg ou URL: http://localhost:59789/DemoAshx/HandlerDemo.ashx Arquivo query string: "" arquivo exibido: Deserto.png
O resultado exibido para a url : http://localhost:59789/DemoAshx/HandlerDemo.ashx?arq=jardim é mostrado a seguir:
Lembrando que embora o resultado ao usar um manipulador ASHX é o mesmo que uma página ASPX o desempenho por conta do uso dos primeiros é da ordem de 10%.
Então quando usar um manipulador ASHX ou um página ASPX:
Use Web Forms quando tiver que expor : |
Use um Manipulador ASHX quando tiver que expor os seguintes conteúdos: |
|
|
E estamos conversados...
Pegue o projeto completo aqui: DemoAshx.zip
Eu sei é apenas ASP .NET, mas eu gosto...
Referências: