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();
}
}
}