+7 votos
167 visitas
Fiz uma rotina utilizando BEF, que consiste em gerar alguns registros e armazenar um relatório no formato PDF. Nesse registro também é armazenado um caminho da web juntamente com o handle do registro criptografado. Cada registro contém um e-mail de cliente. Através do e-mail mando esse link para os clientes.

Pois bem, o que eu preciso é que ao clicar nesse link o cliente baixe esse relatório sem que haja uma identificação/autenticação, ele apenas deve ter acesso ao registro e ao relatório armazenado. A dificuldade é como criar essa pagina que tenha acesso aos dados do sistema e ao mesmo tempo possa ser acessada por esse link.

Existe alguma forma de fazer isso?
por (173 pontos)
editado por | 167 visitas

2 Respostas

+3 votos
Melhor resposta

Esta seria uma proposta de solução, vou detalhar como seria desde o envio do e-mail até a página especializada para fazer o download do relatório.

Regra de negócio (BEF)

Responsável por enviar o link para o usuário, no link é adicionado dois parâmetros o nome do usuário e o handle critografado do relatório, que serão utilizados na página especializada.

 

var mailMessage = new MailMessage();
mailMessage.SendTo = email;

//Gerar um link com dois parâmetros
var urlLinkDefinition = new UrlLinkDefinition(url);
//Nome do usuário
urlLinkDefinition.Parameters.Add("UserName", userName);
//Handle criptografado
urlLinkDefinition.Parameters.Add("EncryptedHandle", encryptedHandle);

mailMessage.Subject = "Relatório";
mailMessage.Body = string.Format(@"Olá {0},

Abaixo o link para download do relatório:

{1}

", userName, urlLinkDefinition.GetEncodedUrl());

mailMessage.Send();

 

Página especializada (WES)

Criar uma pagina ashx no WES, que esteja configurada como uma página publica no web.config:

  <!-- Permitir acesso a usuários não autenticados na página de baixar relatório-->
  <location path="BaixarRelatorio.ashx">
    <system.web>
      <authorization>
        <allow users="?" />
      </authorization>
    </system.web>
  </location>

Na pagina especializada, você deve verificar se os parâmetros são coerentes com a requisição para que seja garantido a segurança:

public class BaixarRelatorio : IHttpHandler, IReadOnlySessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            //prms é o nome do parâtro criado pela classe UrlLinkDefinition
            if (context.Request["prms"] != null)
            {
                var urlLinkDefinition = new UrlLinkDefinition(context.Request.Url.AbsoluteUri);
                urlLinkDefinition.DeserializeParameters(context.Request["prms"].ToString());

                var userName = urlLinkDefinition.Parameters["UserName"].ToString();
                var encryptedHandle = urlLinkDefinition.Parameters["EncryptedHandle"].ToString();

                var entidadeDoRelatorio = null;
                try
                {
                    entidadeDoRelatorio = EntidadeDoRelatorio.Get(userName, encryptedHandle);
                }
                catch (EntityNotFoundException err)
                {
                    throw err;
                }
                
                //Campo do relatório
                FileField campoRelatorio = entidadeDoRelatorio.Fields["CAMPO_DO_RELATORIO"] as FileField;

                MemoryStream stream = new MemoryStream();
                //Carregando o relatório do bdoc
                FileField.RetrieveContents(entidadeDoRelatorio, "CAMPO_DO_RELATORIO", stream);

                System.Net.Mime.ContentDisposition disposition = new System.Net.Mime.ContentDisposition();
                disposition.DispositionType = System.Net.Mime.DispositionTypeNames.Attachment;

                context.Response.ContentType = "application/pdf";
                
                //Adiciona nome do relatório no cabeçalho
                disposition.FileName = HttpUtility.UrlEncode(fileField.Name);
                context.Response.AddHeader("Content-Disposition", disposition.ToString());

                BinaryReader sr = new BinaryReader(stream);
                context.Response.AddHeader("Content-Length", stream.Length.ToString());
                if (stream.Length > 0)
                {
                    sr.BaseStream.Position = 0;
                    context.Response.BinaryWrite(sr.ReadBytes(Convert.ToInt32(stream.Length)));
                }
                context.Response.Flush();

                context.Response.End();

            }
        }

    }

 

por
selecionada por anônimo
+3 votos

Utilizando o WES, basta criar um novo arquivo Generic Handler (pelo Visual Studio): Relatorio.ashx.

Configure o arquivo web.config para permitir o acesso anônimo a esse Handler:

<location path="Relatorio.ashx">
    <system.web>
        <authorization>
            <allow users="?"/>
        </authorization>
    </system.web>
</location>

Implemente o Handler para obter o arquivo de acordo com os parâmetros da URL e retorná-lo ao navegador.

<%@ WebHandler Language="C#" Class="Relatorio" %>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using Benner.Tecnologia.Common;
using Benner.Tecnologia.Common.Instrumentation;
using Benner.Tecnologia.Business;

using Microsoft.Win32;

public class Relatorio : IHttpHandler {

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

    public void ProcessRequest(HttpContext context)
    {
        // Obtenção dos parâmetros
        context.Request.Params.Get("CHAVE");

        // Obtém a entidade (utilizando as informações dos parâmetros)
        EntityBase entity = Entity.Get(EntityDefinition.GetByName("TABELA"), new Criteria());

        FileField fileField = entity.Fields["CAMPO"] as FileField;

        // Obtem os dados do campo e retorna  para o navegador
        MemoryStream memoryStream = new MemoryStream();
        FileField.RetrieveContents(entity, "CAMPO", memoryStream);

        string contentType = "application/octet-stream";
        string contentDisposition = "attachment";

        string fileName = Path.GetFileNameWithoutExtension(fileField.Name).Replace('"', '_');
        string fileExtension = Path.GetExtension(fileField.Name).ToLower();
        switch (fileExtension)
        {
            case ".pdf":
                contentType = "application/pdf";
                contentDisposition = "inline";
                break;
            case ".rtf":
                contentType = "text/rtf";
                contentDisposition = "inline";
                break;
            case ".doc":
                contentType = "application/msword";
                contentDisposition = "inline";
                break;
            case ".xls":
                contentType = "application/vnd.ms-excel";
                contentDisposition = "inline";
                break;
            case ".dat":
                contentType = "application/octet-stream";
                contentDisposition = "attachment";
                break;
            case ".csv":
                contentType = "text/csv";
                contentDisposition = "attachment";
                break;
            default:
                RegistryKey registryKey = Registry.ClassesRoot.OpenSubKey(fileExtension);
                contentType = registryKey != null ? (string)registryKey.GetValue("Content Type", "application/octet-stream") : "application/octet-stream";
                contentDisposition = "attachment";
                break;
        }

        context.Response.ClearHeaders();
        context.Response.ClearContent();
        context.Response.Clear();
        context.Response.ContentType = contentType;
        context.Response.AddHeader("Content-Disposition", String.Format("{0}; filename=\"{1}{2}\"", contentDisposition, fileName, fileExtension));
        context.Response.AddHeader("Content-Length", memoryStream.Length.ToString());

        BinaryReader binaryReader = new BinaryReader(memoryStream);
        if (memoryStream.Length > 0)
        {
            binaryReader.BaseStream.Position = 0;
            context.Response.BinaryWrite(binaryReader.ReadBytes(Convert.ToInt32(memoryStream.Length)));
        }

        context.Response.Flush();
        context.Response.End();
    }
}

 

por (230 pontos)
Melhores Aug 2025
    200 pontos
    Melhores 2025 Jul 28 - Aug 03
    1. Larson

      156 Pontos

    2. danilo.pereira

      96 Pontos

    3. danilo.pereira

      96 Pontos

    4. danilo.pereira

      96 Pontos

    5. luciano.fronza

      61 Pontos

    6. luciano.fronza

      61 Pontos

    7. luciano.fronza

      61 Pontos

    8. diuari.molinari

      52 Pontos

    9. diuari.molinari

      51 Pontos

    10. diuari.molinari

      51 Pontos

    517 perguntas
    566 respostas
    389 comentários
    704 usuários