Como enviar correo en MVC con C# cuando un haya un error

Posted on Posted in .Net, MVC

Una de las formas mas efectivas de saber que ha ocurrido un error en tu aplicación, es al enviar correo en MVC con C# cuando ocurra un error en tu solución, con todos los detalles del mismo (cuando, donde y porque).

Cual es la razón? Bueno, muchas veces cuando hay errores, lo que muchas veces hacemos es guardar todos los errores en un Log (base de datos, archivo en sistema, etc.), pero la verdad es que no los revisamos, y se quedan en el olvido.

Así que en este post, lo que voy a hacer es matar dos pájaros de un tiro, como enviar correo en MVC con C#, y una vez que sepamos como, configurar el correo para mandarse cuando hay un error en la aplicación.

Enviar correo en MVC con C#?

En este ejemplo, yo voy a crear una clase, aunque puede ser implementada en un método en alguna clase de ayuda, utileria, etc.

using System.Net.Mail;

public class Mail
{
    private const string MailErrorSubject = "ERROR EN LA APLICACION"
    private const string MailErrorAccountFrom = "[email protected]"
    private const string MailErrorAccountTo = "[email protected]"
    private const string MailErrorTemplate = @"<h1> {0} </h1>
	                                    TargetSite:   <b>{1}</b>  <hr />
	                                    Source:       <b>{2}</b>  <hr />
                                            StackTrace:   <b>{3}</b>  <hr />
	                                    DateTime:     <b>{5}</b>";
        
    public void SendErrorMail(Exception  ex) {
        var client = new SmtpClient();
        var mailMessage = new MailMessage();
        mailMessage.From = new MailAddress(MailErrorAccountFrom);
        mailMessage.To.Add(MailErrorAccountTo );
        mailMessage.Subject = MailErrorSubject;
        mailMessage.IsBodyHtml = true;
        mailMessage.Body = string.Format(MailErrorTemplate, ex.Message, ex.TargetSite, ex.Source, ex.StackTrace, DateTime.Now.ToString("MMMM dd, yyyy HH:mm tt"));

        client.Send(mailMessage);
    }
}

También tenemos que configurar los parámetros del servicio SMTP para poder enviarlo, aquí es importante que sepas:

  • El host de tu servidor
  • Si soporta mandar correos sin autenticación
  • Si tienes que especificar las credenciales para poder usarlo

El siguiente codigo va en el Web.config, el elemento system.net es un hijo directo del elemento raíz configuration.

<configuration>
  <!--Elementos del web.config-->
  <system.net>
    <mailSettings>
      <smtp>
        <network host="mail.Tu-dominio.com" defaultCredentials="false" 
                 userName="[email protected]" password="mi-contraseña-super-secreta" />
      </smtp>
    </mailSettings>
  </system.net>
</configuration>

Si tu host soporta el envío de correo sin autenticar entonces basta con que solo especifiques el atributo host en el elemento network.

Envié un correo de prueba, creando una excepción vacía, solamente para mostrar como se ve el correo cuando se manda:

Enviar correo en MVC con C#

Configurar la aplicación para que se envíe el correo cuando un error ocurra?

Ahora que ya tenemos configurado el servicio SMTP y la clase que va a mandar el correo, solamente tenemos que configurar la aplicación web para que cuando ocurra un error que no manejemos en la aplicación, nos mande avise mandando el correo, lo cual lo hacemos añadiendo el siguiente método al archivo Global.asax.cs.

protected void Application_Error(object sender, EventArgs e)
{
    var exception = Server.GetLastError();
    Response.Clear();

    var mail = new Mail();
    mail.SendErrorMail(exception);
}

Y liiiiiiisto.

Con esto debería de ser suficiente para que cada vez que haya un error en tu app, tu estés al tanto.

Tu correo se envía localmente pero no cuando esta en el servidor?

Si tu correo no sale una vez que esta en el servidor, entonces lo que tienes que hacer es configurar el elemento CustomErrors de la siguiente manera:

<configuration>
  <!--Elementos del web.config-->
  <system.web>
    <customErrors mode="Off"/>
  </system.web>
</configuration>

La razón de porque es necesaria esta configuración la podemos encontrar en la excelente respuesta de Jesse Webb en Stack Overflow en la cual explica la diferencia del comportamiento de este elemento localmente y una vez se publica en el servidor.

Tu no se envía ni localmente?

Bueno, esto puede ser porque el puerto esta bloqueado en tu maquina, intenta publicar tu solución en el servidor web y si no se envía entonces revisa el punto de arriba ;).