Generic Handlers possuem a extensão ASHX, e funcionam basicamente como páginas ASPX. A grande diferença é que um Generic Handler não é uma página. Ele é geralmente utilizado quando precisamos de uma URL para realizar alguma tarefa, mas não precisamos de nenhuma interface de usuário para tal operação.

Generic Handlers são como os Custom Handlers, escritos em C# ou VB.NET, que são classes que implementam a interface IHttpHandler. Um HttpHandler é responsável por atender as requisições de um Browser. O IHttpHandler é uma interface do ASP.NET que define um contrato para a implementação de processos síncronos de requisição Web Http, usando HttpHandlers customizados.

Para criar um Generic Handler em sua aplicação ASP.NET Web Forms, é necessário utilizar o template Generic Handler, como mostra a Figura 1.

Figura 1. Template ASP.NET para Generic Handler

Como dito, um Generic Handler implementa a interface IHttpHandler. No exemplo da Listagem 1 é possível ver a implementação de um Generic Handler que tem a responsabilidade de realizar upload de arquivos.

Listagem 1. Generic Handler para upload de arquivos

using System;
  using System.IO;
  using System.Web;
   
  namespace ExemploUploadDx.Web
  {
      public class UploadHandler : IHttpHandler
      {
          string FilePath { get; set; }
          string FileName { get; set; }
          int PackageCount { get; set; }
          int PackageNumber { get; set; }
   
          public bool IsReusable { get { return false; } }
   
          public void ProcessRequest(HttpContext context)
          {
              ProcessQueryString(context);
              ProcessFile(context);
          }
   
          void ProcessQueryString(HttpContext context)
          {
              var query = context.Request.QueryString;
              FilePath = Uri.UnescapeDataString(query["filePath"]);
              FileName = Uri.UnescapeDataString(query["fileName"]);
              PackageCount = int.Parse(query["packageCount"]);
              PackageNumber = int.Parse(query["packageNumber"]);
          }
   
          void ProcessFile(HttpContext context)
          {
              var serverFileName = GetServerPath(context.Server, FilePath, FileName);
              var fileMode = File.Exists(serverFileName) && PackageNumber > 0 ?
                  FileMode.Append :
                  FileMode.Create;
   
              using (var reader = new BinaryReader(context.Request.InputStream))
              {
                  using (var writer = new BinaryWriter(File.Open(serverFileName, fileMode)))
                  {
                      var buffer = new byte[4096];
                      int bytesRead;
                      while ((bytesRead = reader.Read(buffer, 0, buffer.Length)) != 0)
                          writer.Write(buffer, 0, bytesRead);
                  }
              }
          }
   
          static string GetServerPath(HttpServerUtility server, string filePath, string fileName)
          {
              return server.MapPath(Path.Combine(filePath, Path.GetFileName(fileName)));
          }
      }
   
  }

O principal método do Generic Handler é o ProcessRequest. Ele recebe um HttpContext, que carrega o contexto da requisição feita para o Generic Handler. Lembre-se, ele é como uma página ASPX, que é requisitado através de uma URL.

O método ProcessQueryString deste exemplo é responsável pelo tratamento das QueryStrings do contexto, para identificar o nome do arquivo que será feito o upload, assim como a pasta onde o arquivo será armazenado no servidor.

Já o método ProcessFile é responsável por realizar o upload do arquivo. A propriedade Request.InputStream do contexto, carrega os binários do arquivo que será feito o download. Basta ler esse binário do contexto e gravá-lo no servidor.

Este é um exemplo de como é útil o Generic Handler. Ele pode ser utilizado em diversas outras ocasiões, onde não é preciso ter toda a estrutura de uma página ASPX para realizar uma determinada tarefa. Grande Abraço e até a próxima!