jueves, 30 de agosto de 2012

MailMessage – Adjuntar Imagen en el cuerpo del Mail (3/3)

 

Introducción


En la creación de un mail cuyo cuerpo sea HTML se puede requerir que una imagen forme parte del mismo, pero ubicarla como parte del mail será necesario no solo embeberla dentro del contenido sino poder referenciarla para ubicarla en una posición concreta

 

Imagen como recurso


En el archivo embebido como recurso dentro del assembly se define el html del cuerpo del mail

<html>
	<body>
		<h2> Documento con imagen adjunta</h2>
		<br/>
		<img src="cid:estadistica">
	</body>
</html>

en este se usa el cid junto a un nombre para ubicar el recurso de la imagen que se asocia al mail

La definición del recurso se debe realizar en una vista alternativa del mail

AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);

string imagePath = Path.Combine(TestContext.DeploymentDirectory, "estadistica.jpg");
LinkedResource logo = new LinkedResource(imagePath);
logo.ContentId = "estadistica";
htmlView.LinkedResources.Add(logo);

mail.AlternateViews.Add(htmlView);

es allí donde se define el id del resource de la vista html

El test completo además de la vista html se incluye una vista en texto plano en caso de quien reciba el correo lo este visualizando desde un cliente que no soporta html

[TestMethod]
public void SendMailBodyImage()
{

    //
    // se define la lista de destinatarios
    //
    List<string> destinatarios = new List<string>()
    {
        "xx@gmail.com",
        "xx@hotmail.com"
    };


    MailMessage mail = new MailMessage()
    { 
        Subject = "Mail Test con formato html",
        IsBodyHtml = true
    };


    //
    // se asignan los destinatarios
    //
    foreach (string item in destinatarios)
    {
        mail.To.Add(new MailAddress(item));
    }

    //
    // se crea el mensaje como texto plano
    //
    string plaintextBody = "";

    using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MailSendTest.MailPlainTextBody.txt"))
    using (StreamReader reader = new StreamReader(stream))
    {
        plaintextBody = reader.ReadToEnd();
    }

    AlternateView plainTextView = AlternateView.CreateAlternateViewFromString(plaintextBody, null, MediaTypeNames.Text.Plain);
    mail.AlternateViews.Add(plainTextView);


    //
    // se crea el mensaje html
    //
    string htmlBody = "";

    using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MailSendTest.MailHtmlBody.txt"))
    using (StreamReader reader = new StreamReader(stream))
    {
        htmlBody = reader.ReadToEnd();
    }

    AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);
   
    string imagePath = Path.Combine(TestContext.DeploymentDirectory, "estadistica.jpg");
    LinkedResource logo = new LinkedResource(imagePath);
    logo.ContentId = "estadistica";
    htmlView.LinkedResources.Add(logo);

    mail.AlternateViews.Add(htmlView);


    //
    // se define el smtp
    //
    SmtpClient smtp = new SmtpClient();
    smtp.Send(mail);


}

Definir la imagen en la carpeta output del Test


Para que el proyecto de test funcione será necesario que la imagen que se adjunta al mail sea ubicada en la carpeta donde el test compila.

Para automatizar esta acción se definir un Test Setting, para ello en la sección “Solution Items” se agrega un nuevo ítem

imagen1

imagen2

Una vez que se crea, solo se hace doble click en el archivo de extensión .testsettings y se define la carpeta que contiene la imagen

imagen3

Esto hará que se copie el imagen que se adjunta en el test, y se pueda localizar dinámicamente usando: TestContext.DeploymentDirectory

Código


Se utiliza VS 2010 para desarrollar el ejemplo

[C#]
 

lunes, 27 de agosto de 2012

MailMessage–Adjuntar Archivo sin bloquearlo (2/3)

 

Introducción


Cuando se necesita enviar un mail que adjunte un documento se suele proporcionando directamente la ruta directa al archivo, la librería smtp que proporciona .net realizara correctamente el attach pero lo mantendrá bloqueado, es por eso que una operación posterior que requiera eliminarlo generara un mensaje como ser

imagen1

 

Adjuntar Archivo sin bloquearlo


Para adjuntar un archivo sin bloquearlo la clave esta en asignar un stream al attach del mail y no directamente el archivos indicando su ruta física.

En este caso se crea un método que ayudara en esta tarea, tomando la ruta del archivo y devolviendo el Stream:

public Stream GetStreamFile(string filePath)
{
    using (FileStream fileStream = File.OpenRead(filePath))
    {
        MemoryStream memStream = new MemoryStream();
        memStream.SetLength(fileStream.Length);
        fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);

        return memStream;
    }
}

Este método es usado en la línea:

mail.Attachments.Add(new Attachment(GetStreamFile(pdfpath), Path.GetFileName(pdfpath), "application/pdf"));

además de asignar el Stream del archivo se proporciona el nombre y el tipo que se adjunta.

El código completo del test usa la librería iTextSharp para crear un archivo pdf de prueba que será adjunto al mail y finalmente eliminado.

[TestMethod]
public void SendMailAttachFile()
{

    //
    // se genera el pdf que luego se adjuntara al mail
    //
    string pdfpath = Path.Combine(TestContext.TestDeploymentDir, "PDFMailAttach.pdf");

    Document document = new Document();
    PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(pdfpath, FileMode.Create));

    document.Open();
    document.Add(new Paragraph("Documento Adjunto sin Bloquear"));
    document.Close();



    //
    // se define la lista de destinatarios
    //
    List<string> destinatarios = new List<string>()
    {
        "xx@gmail.com",
        "xx@hotmail.com"
    };


    //
    // se crea el mensaje
    //
    string body = "";
   
    using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MailSendTest.MailBody.txt"))
    using (StreamReader reader = new StreamReader(stream))
    {
        body = reader.ReadToEnd();
    }

    MailMessage mail = new MailMessage()
    {
        Body = body,
        Subject = "Mail Test con adjunto",
        IsBodyHtml = false
    };

    //mail.Attachments.Add(new Attachment(pdfpath, "application/pdf"));
    mail.Attachments.Add(new Attachment(GetStreamFile(pdfpath), Path.GetFileName(pdfpath), "application/pdf"));

    //
    // se asignan los destinatarios
    //
    foreach (string item in destinatarios)
    {
        mail.To.Add(new MailAddress(item));
    }


    //
    // se define el smtp
    //
    SmtpClient smtp = new SmtpClient();
    smtp.Send(mail);


    //
    // se elimina el archivo porque no estara bloqueado
    //
    File.Delete(pdfpath);

    Assert.IsFalse(File.Exists(pdfpath));

}

Código


[c#]