Posteado por: toniogago | 13 noviembre 2009

Enviar email con WebDav y Exchange Server


Introducción
Recientemente he necesitado implementar en una página ASP (no ASP.NET) el envío de correos electrónicos para una distribución de documentación de las normas ISO. Lo empecé a hacer en una DLL con Visual Basic. Para ello utilicé WebDav contra un Exchange Server 2003. Al hacer las pruebas con el Visual Studio no hubo problemas. Éstos me vinieron cuando quise ponerlo en producción. Al estar en un entorno inpersonate, el envío del correo me fallaba.

Como el servidor está sobre un IIS, me creé un directorio virtual con ASP NET 2. En este directorio puedo alojar páginas aspx y programar asp.net

Cómo lo hago
Primero nos creamos una página aspx. No hace falta que introduzcamos ningún control, a menos que queramos ir informando al usuario de los pasos que vamos dando mediante programación.

El código lo vamos a introducir en este caso en el evento Page_Load. En este ejemplo primero se va a crear el mensaje en la carpeta Borradores y luego se envía.

Primero creamos las variables con las URI de destino. Con este código nos crearemos una credencial para el servidor exchange.

Dim strAlias as String = "codigodeusuario"
Dim strServer as String = "servidor"
Dim strSubject as String = "Asunto"
Dim strMailboxURI as String, strSubURI as String, strTempURI as String
'URI para las credenciales.
strMailboxURI = "http://" & strServer & "/exchange/" & _
                strAlias & "@dominio.com"
strSubURI = "http://" & strServer & "/exchange/" & strAlias _
          & "@dominio.com/##DavMailSubmissionURI##/"
strTempURI = "http://" & strServer & "/exchange/" & strAlias & _
            "@dominio.com/Borradores/" & strSubject & ".eml"

Para solventar el tema de modo inpersonate utilizo credenciales guardadas en una caché:

'El dominio es el que se utiliza para acceder al correo
'antes del backslash. Ejemplo vigo\usuario
Dim strDomain as String = "dominio"
Dim strPassword as String = "!Password"
Dim MyCredentialCache As System.Net.CredentialCache
MyCredentialCache = New System.Net.CredentialCache
MyCredentialCache.Add(New System.Uri(strMailboxURI), _
    "NTLM", _
    New System.Net.NetworkCredential(strAlias,
    strPassword, strDomain) _
)

Para enviar el correo guardamos en 2 variables de cadena el cuerpo del mensaje y el código rfc822 del email:

Dim strEMAIL as String
Dim strBody as String = "<H1>Mensaje con WebDav</H1>"
strEMAIL = "From: usuario@dominio.com" & vbNewLine
strEMAIL &= "To: destinatario@dominio.com" & vbNewLine
strEMAIL &= "Subject: " & strSubject & vbNewLine
strEMAIL &= "Date: " & Format(Now, "dd/mm/yyyy") & vbNewLine
strEMAIL &= "X-Mailer: miMailer" & vbNewLine
strEMAIL &= "MIME-Version: 1.0" & vbNewLine
strEMAIL &= "Content-Type: text/html; charset=utf-8" & vbNewLine & vbNewLine
'Los dos vbNewLine le indican al servidor el fin de la cabecera.
'Ahora le añadimos el cuerpo del mensaje.

strEMAIL &= strBody & vbNewLine

Ahora mediante una petición web enviamos el mensaje a una carpeta temporal. Si la carpeta no existe, el servidor nos devolverá en la respuesta un error. Utilizaremos la clase HttpWebRequest para enviar la petición y HttpWebResponse para ver el estado del envío:

Dim PUTRequest As System.Net.HttpWebRequest
Dim PUTResponse As System.Net.HttpWebResponse
Dim bytes() As Byte
' Creamos el objeto HttpWebRequest.
Try
   PUTRequest = CType(System.Net.WebRequest.Create(strTempURI), _
                System.Net.HttpWebRequest)
   ' Le Añadimos las credenciales
   PUTRequest.Credentials = MyCredentialCache
   ' Especificamos el método PUT.
   PUTRequest.Method = "PUT"
   ' Codificamos el mensaje utilizando UTF-8
   bytes = System.Text.Encoding.UTF8.GetBytes(strEMAIL)
   ' Establecemos la longitud del mensaje.
   PUTRequest.ContentLength = bytes.Length
   'Obtenemos la referenciaa del stream de la petición.
   PUTRequestStream = PUTRequest.GetRequestStream()
   'Escribimos el mensaje en el stream de la petición.
   PUTRequestStream.Write(bytes, 0, bytes.Length)
   ' Cerramos el objeto Stream para liberar la conexión.
   PUTRequestStream.Close()
   PUTRequest.ContentType = "message/rfc822"
   ' Colocamos el mensaje en la capeta de Borradores
   PUTResponse = CType(PUTRequest.GetResponse(), System.Net.HttpWebResponse)

Ahora para enviar el correo, a través de HttpWebRequest lo enviamos:

   ' Creamos el Objeto HttpWebRequest para MOVERLO (enviarlo).
   MOVERequest = CType(System.Net.WebRequest.Create(strTempURI), _
                 System.Net.HttpWebRequest)
   ' Add the network credentials to the request.
   MOVERequest.Credentials = MyCredentialCache
   ' Especificamos el método MOVE.
   MOVERequest.Method = "MOVE"
   ' Establecemos la cabecera Destination para el
   ' mail submission URI.
   MOVERequest.Headers.Add("Destination", strSubURI)
   ' Enviamos el mensaje moviéndolo desde la carpeta Borradores
   ' al mail submission URI.
   MOVEResponse = CType(MOVERequest.GetResponse(), System.Net.HttpWebResponse)
Catch ex As Exception
   'Si ocurre algún error lo podremos manejar aquí.
End Try

Ahora sólo falta comprobar que el destinatario recibió el correo.

Esta prueba la hice en un Exchange Server 2003 con las opciones de instalación que vienen por defecto.

Un saludo.

Anuncios

Responses

  1. […] un post anterior expliqué cómo enviar un correo con WebDav y Exchange Server (ver) y en otro expliqué cómo renderizar directamente el contendio de un informe en PDF (ver). Ahora […]


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Categorías

A %d blogueros les gusta esto: