Hola :D, en esta ocasión les quiero compartir una solución a un problema que tuve hace un tiempo y que tal vez les pueda servir.

Problema

Empecemos por el problema, tengo un servicio WCF hosteado en un website de IIS, el cual como parte de la lógica de negocio debe ser el encargado del envió de correos electrónicos cuyo contenido es generado dinámicamente.
Problema de correo
El dolor de cabeza comienza la hora de crear los correos ya que no tenemos muchas alternativas. En sitios web con el framework MVC yo usaba MvcMailer el cual me brindaba la posibilidad de usar el motor de vistas de razor para crear el cuerpo de mis correos, lo cual lo hace mucho mas fácil y mantenible. Pero dado que estamos hablando de un servicio WCF no contamos con esta opción, la siguiente opción sería utilizar una plantilla en un archivo de texto(.txt o .html) y utilizar un StringBuilder o String.Format para generar el cuerpo de mi correo, pero es un procedimiento tedioso y muy propenso a errores.

Solución

Una solución mucho más elegante es el uso de un motor de vistas para nuestros mails, en este caso resulta muy complicado incluir el motor de razor debido a un gran número de dependencias con el framework de MVC, así que optamos por usar un motor de vistas portado de JavaScript a .NET que es muy popular Handlebars.

Manos a la obra

Estamos asumiendo que tenemos un proyecto de WCF - Web Host abierto y funcionando.

  1. Instalamos el paquete de Handlebars.NET.

    PM> Install-Package Handlebars.Net

  2. Agregamos una carpeta que contendrá nuestras plantillas, la organización de las mismas puede ser en subcarpetas, para este caso por simpleza lo dejaremos en una sola carpeta templates.

  3. Para que las aplicaciones no puedan acceder a la carpeta, agregaremos una pequeña configuración de seguridad en el web.config.

  4. Agregamos una llamada Mail donde crearemos una clase estática llamada MailGenerator.

  5. Agregamos una propiedad pública estática que haga referencia la carpeta de nuestras templates.

     //Aquí guardamos la ruta relativa de nuestras plantillas
     public static string TemplateFolder = "~/templates";
    
  6. Agregamos un método estático que reciba un objeto que representa el modelo de nuestra plantilla y el nombre de la plantilla.

     public static string GetHtml<T>(T data,string templateName)
    
  7. Ahora obtenemos la ruta física de nuestro folder de plantillas y lo combinamos con el nombre de nuestra plantilla para obtener la ruta completa. Verificamos si el archivo existe, si no es así lanzamos una excepción. Si el archivo existe leemos el texto de nuestra plantilla.

     var basePath = System.Web.Hosting.HostingEnvironment.MapPath(TemplateFolder);
     var totalPath = Path.Combine(basePath, templateName);
    
     if (!File.Exists(totalPath))
             throw new InvalidOperationException("La plantilla {0} no se ha encontrado en el folder de plantillas.");
    
     var templateText = File.ReadAllText(totalPath);
    
  8. Ahora que tenemos la plantilla, agregamos el siguiente ‘using’ para poder usar el motor de vistas Handlebars.

     using HandlebarsDotNet;
    
  9. Para generar el resultado final primero compilamos la vista para poder utilizar luego nuestro modelo y generar el resultado.

     var template = Handlebars.Compile(templateText);
    
  10. Generar el resultado se vuelve tan simple como:

    var result = template(data);
    return result;
    

    A continuación, pueden ver el código completo.

  11. Ahora para poder probar nuestra clase agregamos una nueva template a nuestro folder, al cual llamaremos para este ejemplo welcome.html. (El contenido de la template se muestra a continuación y es una pequeña modificación de una plantilla muy simple de nuestro amigo @leemunroe).

    <div class="content">
      <table>
       <tr>
        <td>
          <p>Hi there,{{Name}}</p>
          <p>Sometimes all you want is to send a simple HTML email with a basic design.</p>
          <h1>{{Message}}</h1>
          <p>{{Date}}</p>
          <h2>Welcome</h2>                                
          ...               
    

    Se han omitido varias líneas de código HTML para clarificar. Puedes ver el archivo completo aqui.
    Lo interesante de este fragmento es la sintaxis con la que se accede a los datos del modelo que le pasamos a nuestra plantilla, a través de la sintaxis de llaves dobles ({{ }}). Si necesitan más detalles acerca de la sintaxis de Handlebars pueden revisar este artículo.

  12. Configuramos nuestro cliente SMTP, es recomendable guardar la configuración de correo en el web.config por flexibilidad. En este caso por ser una prueba estoy configurando para que el correo se genere y se guarde en una carpeta en lugar de enviarse. Si necesitas saber cómo configurar tu cuenta de correo en el web.config puedes referirte a este articulo.

  13. Finalmente en nuestro servicio de WCF llamamos a nuestra clase para generar el HTML y utilizamos (en este caso) un cliente SMTP para el envío de correo. Cabe destacar que el modelo que se le pasa a la vista está creado con valores fijos por simplificar el ejemplo pero podrían provenir de la base de datos, calcularse y generarse de la manera más adecuada a su problema

Veámoslo en acción

Ejecutamos nuestro servicio de WCF y ejecutamos el método de ejemplo que hemos creado para este caso.
Ejecucion del servicio WCF

Y tras ejecutar correctamente y revisar (en mi caso) mi carpeta temporal donde se guarda el correo generado. Podemos ver como se generó correctamente.

Email generado

No se olviden que pueden acceder al código de ejemplo completo y funcionando en GitHub https://github.com/jesulink2514/WcfDemoMail

Y eso sería todo, ahora podemos generar emails personalizados utilizando el motor de vistas de Handlebars, que como pueden ver es muy sencillo de usar. Espero pueda servirles, cualquier cosa pueden dejar un comentario y les responderé a la brevedad.

Y como dice WillyDevOps :D ;) ...