{ WillyXoft .NET }

Blog de Willy Mejía sobre Microsoft .NET Framework y temas relacionados...

<December 2008>
SuMoTuWeThFrSa
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910


Navigation

e-Grupos / Foros

Web/Blog Amigos

INETA & MUGs

Subscriptions

News

WillyXoft

Post Categories

Article Categories



Enviando correo electrónico con autenticación desde Visual Basic .NET Rated Good [4 out of 5].

Por Willly Mejía [WillyXoft]

Para que una aplicación .Net pueda realizar envío de correo electrónico normalmente se emplea el espacio de nombres System.Web.Mail que contiene las clases que permiten construir y enviar mensajes mediante el componente de mensajería CDO (Collaboration Data Objects) formalmente "Microsoft CDO for Windows 2000 Library" incluido en Windows 2000 y posteriores. El mensaje de correo se entrega por medio del servicio de correo SMTP (Simple Mail Transport Protocol) incluido en Windows con IIS o bien mediante algún otro servidor SMTP. Las clases de este espacio de nombres se pueden utilizar desde cualquier aplicación administrada ya sea de consola, Windows o ASP.NET.

Un sencillo ejemplo que ilustra lo fácil que es enviar correo electrónico desde Visual Basic .NET lo vemos en el siguiente página: http://support.microsoft.com/default.aspx?scid=314201

Ahora bien, existe un problema en los siguientes escenarios:

  • Cuando deseamos enviar un mensaje hacia Internet a través de Exchange Server.
  • Cuando deseamos enviar un mensaje hacia un servidor SMTP externo que requiere autentificación.

En realidad en ambos escenarios el problema es el mismo: la autenticación. Si examinamos las clases de System.Web.Mail no vemos ningún miembro que sirva para especificar dicha información, entonces ¿Como podemos mandar correo electrónico con autenticación? las posibilidades son:

  • Para el .Net Framework 1.0 (v1.0.XXXX), usar la Biblioteca COM de CDO por medio de Interoperabilidad.
  • Para el .Net Framework 1.1 (v1.1.XXXX), emplear el nuevo miembro Fields de MailMessage.
  • Emplear algún componente de terceros, o incluso crear uno propio.

En el presente artículo analizaremos las dos primeras.

Usando CDO para el envío de mensajes con autenticación.

Esta es, la solución mas obvia para el envío de mensajes con autenticación y la única (gratuita) para el .NET Framework 1.0. Para empezar tenemos que tomar en cuenta que nuestro código tendrá que emplear la Biblioteca de tipos de CDO a través de Interoperabilidad COM, por ello lo primero que tenemos que hacer es crear nuestro Ensamblado de Interoperabilidad (IA).

Desde su IDE puede hacerlo agregando la referencia COM de dicho componente, para ello:

  1. En nuestro entorno hacer click derecho sobre el arbol "Referencias" y elegimos "Agregar referencia...".
  2. En la ventana que emerge pasamos al tabulador COM
  3. En en el listado que aparece buscaremos "Microsoft CDO for Windows 2000 Library", lo seleccionamos con doble click o a través del botón correspondiente, por último pulsamos el botón  "Aceptar".
O bien, en la línea de comandos lo obtenemos escribiendo:
    >tlbimp cdosys.dll /out:Interop.CDO.dll
Si todo resulto bien veremos un mensaje como el siguiente:
    Type library imported to Interop.CDO.dll

Una vez obtenido el Ensamblado de Interoperabilidad, ya sea desde nuestro IDE o desde la línea de comandos, podemos examinarlo mediante algun Inspeccionador de Ensamblados como el "Examinador de Objetos" de Visual Studio .NET, el "ClassBrowser" de WebMatrix, o bien el "Desensamblador IL" (ILDasm.exe) del .NET Framework SDK.

El objeto principal de CDO utilizado para la construcción y envío de mensajes es Message. por lo que será el primero que analizaremos:

CDO.Message

Este objeto entre las propiedades y métodos necesarios para la construcción y envío de mensajes tiene un miembro llamado Configuration, que es la implementación de la interface IConfiguration, la cual define las propiedades y métodos para la configuración de CDO.

Message.Configuration

La configuración de CDO se establece a través de Campos (Fields). pero ¿Que es un Campo para CDO? Veamos lo que dice la documentación:

"'Microsoft CDO for Windows 2000' emplea URIs (Uniform Resource Identifiers) para cualificar o delimitar los nombres de campos y sus definiciones semánticas. Cada campo accesible a través de la colección Fields esta comprendido de un prefijo de espacio de nombres (namespace) y un nombre local. El prefijo del espacio de nombres es una referencia URI utilizada para cualificar o delimitar la definición semántica de la propiedad..."
 Extraido de: http://msdn.microsoft.com/library/en-us/cdosys/html/_cdosys_fields.asp

Podemos decir entonces que son una serie de propiedades con nombre compuesto por un Espacio de Nombre y un Nombre Local que se almacenan y acceden a través de una colección de nombre Fields, a los cuales se le asigna un valor que los califican o delimitan.

Fields("URLnamespace/localname") = valor

Los campos se establecen mediante una implementación de la colección IConfiguration.Fields de tipo ADODB.Fields. Esta implementación esta asociada al objeto Configuration quien a su vez esta asociado a los distintos objetos COM de CDO. 

CDO.Configuration

Configuration.Fields

Es el objeto Configuration entonces el que se emplea para definir parámetros de configuración específicos al objeto CDO.Message. Para ello debemos crear un objeto Configuration para a través de su colección Fields establecer los valores de los Campos necesarios para realizar la autenticación en el servicio SMTP para después asignar dicha configuración al objeto Message y de ese modo lograr nuestro objetivo.

Dim oMsg As New CDO.Message()
Dim iConfig As  New CDO.Configuration()
Dim Flds As ADODB.Fields = iConfig.Fields
'Modificacion de los campos...
oMsg.Configuration=iConfig

Todos los Campos que necesitamos establecer se encuentran bajo el Espacio de Nombres CDO:

"http://schemas.microsoft.com/cdo/configuration/"

Para mayor información sobre este Espacio de Nombres ver: http://msdn.microsoft.com/library/en-us/cdosys/html/_cdosys_schema_configuration.asp

Los Campos correspondientes al Espacio de Nombres "http://schemas.microsoft.com/cdo/configuration/" están agrupadas en la Biblioteca de CDO bajo el Módulo (desde el .Net Framework se ve como una clase abstracta) CdoConfiguration y están representados por Constantes que equivalen a los "nombre completo" del Campo, tal y como vemos en la siguiente imagen: 

CDO.cdoConfiguration

Así por ejemplo, la constante seleccionada cdoSMTPAuthenticate equivale al Campo de Nombre Local smtpauthenticate, esta constante equivale al "nombre completo" correspondiente al Campo el cual es: "http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"

cdoSMTPAuthenticate

Es mediante el Campo smtpauthenticate que podemos indicar el mecanismo de autenticación requerida para enviar mensajes, los valores que se le asigna son los listados por el Enumerado CdoProtocolsAuthentication, el cual alberga a tres constantes: cdoAnonymous (0), cdoBasic (1) y  cdoNTLM (2). En otras palabras, podemos especificar 3 tipos de autentificación: Anónima (sin autenticación), Básica (simple) o NTLM (integrada). Si deseáramos enviar un correo electrónico por medio de un servidor SMTP externo a la red local necesitamos usar autenticación Básica.

La documentación de CDO menciona que, para que el Campo smtpauthenticate sea tomado en cuenta debe establecerse a su vez el Campo sendusing ("http://schemas.microsoft.com/cdo/configuration/sendusing"), igual a la constante cdoSendUsingPort (2) albergada por el Enumerado CdoSendUsing; este campo define si se debe enviar el mensaje utilizando el servicio local SMTP (si es que el hot local tuviese el servicio SMTP instalado) o un servicio SMTP externo directamente sobre la red de trabajo local, que es el que debemos establecer. Así mismo menciona que también debe establecerse el valor del Campo smtpserver ("http://schemas.microsoft.com/cdo/configuration/smtpserver") la dirección IP específica o el nombre DNS del host que alberga el servicio SMTP, y en caso de ser necesario, debe establecerse el valor numérico del puerto del mismo en el Campo smtpserverport ("http://schemas.microsoft.com/cdo/configuration/smtpserverport"). 

Por último y mas importante, para establecer las credenciales de autenticación requeridas para la conexión con el servicio SMTP, deben establecerse los valores de los Campos sendusername ("http://schemas.microsoft.com/cdo/configuration/sendusername") y sendpassword ("http://schemas.microsoft.com/cdo/configuration/sendpassword") correspondientes a el nombre (login) y la contraseña de usuario. Estos dos Campos junto con el Campo smtpauthenticate son los indispensables para llevar a cabo nuestro cometido.

Pues bien, con lo estudiado hasta aquí podemos elaborar un ejemplo con VB.NET: Para ello creamos un Proyecto de Consola y agregamos la referencia de CDO, o bien, simplemente creamos un archivo de nombre Module1.vb con Visual Notepad. Después, en cualquiera de los casos, introducimos el código siguiente:

Option Explicit On 
Module Module1 
    Sub Main()
        Const ConfigNamespace as  String = _
            "http://schemas.microsoft.com/cdo/configuration/" 
        Dim oMsg As New CDO.Message() 
        Dim iConfig As New CDO.Configuration() 
        Dim Flds As ADODB.Fields = iConfig.Fields
        With Flds 
            .Item(ConfigNamespace & "smtpserver").Value = "smtp.mail.dominio" 
            .Item(ConfigNamespace & "smtpserverport").Value = 25 
            .Item(ConfigNamespace & "sendusing").Value = _ 
                CDO.CdoSendUsing.cdoSendUsingPort 
            .Item(ConfigNamespace & "sendusername").Value = "usuario" 
            .Item(ConfigNamespace & "sendpassword").Value = "contraseña" 
            .Item(ConfigNamespace & "smtpauthenticate").Value = _ 
                CDO.CdoProtocolsAuthentication.cdoBasic 
            .Update() 
        End With 
        With oMsg 
            .Configuration = iConfig 
            .From = "usuario@dominio" 
            .To =  "alguien@dominio" 
            .Subject =  "Test CDO con VB.NET" 
            .TextBody = "Hola Mundo" 
            .Send() 
        End With 
        oMsg = Nothing 
        iConfig = Nothing 
    End Sub 
End Module

Compilamos desde nuestro IDE, o bien, para compilar desde la línea de comandos:

>vbc Module1.vb /r:Interop.CDO.dll,adodb.dll

Nota: ADODB.DLL es el PIA de ADO que por lo general se encuentra en: "%programfiles%\Microsoft.NET\Primary Interop Assemblies" de lo contrario deberá crearlo por su cuenta.

Como puede observarse, el enviar mensajes con autenticación con CDO solo requiere conocer y establecer unos cuantos Campos a sus valores adecuados. Lo anterior podemos realizarlo también con el .Net Framework 1.1 pero esta versión tiene la ventaja de poderlo realizar sin necesidad de incorporar la Referencia COM a CDO.

Usando MailMessage.Fields para el envío de mensajes con autenticación.

Las clases involucradas en el Namespace System.Web.Mail para la construcción y envío de correo electrónico desde .NET son::

En la documentación del versión 1.1 del .Net Framework se observa que la clase MailMessage de System.Web.Mail tiene un nuevo miembro llamado Fields, mismo que hasta el día de hoy no está documentado:

MailMessage

MailMessage.Fields

Lo único que nos dice la documentación es que es de tipo System.Collections.IDictionary. Mas ahora que ya hemos visto como funciona CDO podríamos suponer, al menos como una aproximación, que podría tratarse de la colección Fields del objeto Configuration asociado al objeto Message de CDO.

Con espíritu investigador realicemos una prueba en base al código anterior cambiando los objetos CDO por sus equivalentes en System.Web.Mail, empleando un System.Collections.IDictionary en lugar de ADODB.Fields, así como cambiando las nombres de las constantes CDO por sus valores numéricos correspondientes para evitar cualquier referencia a CDO. Esto nos da como resultado el siguiente código:

Option Explicit On 
Module Module1 
    Sub Main()
        Const ConfigNamespace as  String = _
            "http://schemas.microsoft.com/cdo/configuration/" 
        Dim oMsg As New System.Web.Mail.MailMessage 
        Dim Flds As System.Collections.IDictionary 
        Flds = oMsg.Fields 
        With Flds 
            .Add(ConfigNamespace & "smtpserver""smtp.mail.dominio"
            .Add(ConfigNamespace & "smtpserverport", 25) 
            .Add(ConfigNamespace & "sendusing", 2) 
            .Add(ConfigNamespace & "sendusername""usuario"
            .Add(ConfigNamespace & "sendpassword""contraseña"
            .Add(ConfigNamespace & "smtpauthenticate", 1) 
        End With 
        With oMsg 
            .From = "usuario@dominio" 
            .To =  "alguien@dominio" 
            .Subject =  "Test MailMessage.Fields con VB.NET" 
            .Body = "Hola Mundo" 
        End With 
        System.Web.Mail.SmtpMail.Send(oMsg) 
    End Sub 
End Module

Observe que dado a que se especificó el host del servicio SMTP mediante el Campo "smtpserver" ya no es necesario hacerlo mediante la propiedad SmtpMail.SmtpServer. Por otro lado también, si se emplea SmtpMail.SmtpServer se pueden omitir los Campos "smtpserver", "smtpserverport" y "sendusing" siendo sólo necesario especificar los tres campos restantes: "sendusername", "sendpassword" y "smtpauthenticate".

Compilamos el ejemplo sin ningun error, despues ejecutamos unas cuantas veces enviando correos... ¡Funciona!. Luego entonces, el miembro Fields de System.Web.Mail.MailMessage equivale, por asi decirlo, al miembro Fields de CDO.Configuration asociado a CDO.Message tal y como se ilustró anteriormete.

Por lo visto entonces podemos enviar mensajes con autenticación sin necesidad de emplear directamente la Biblioteca COM de CDO gracias a System.Web.Mail.MailMessage.Fields, pero recuerde que éste esta presente sólo a partir de la versión 1.1 del .Net Framework, si por alguna razón aún trabaja con la versión 1.0 tendrá que emplear el primer método, o bien, actualizarse a la versión 1.1.

Ahora talvez se preguntará ¿MailMessage.Fields servirá para los Campos de otros Espacios de Nombres de CDO? Talvez sí, pero eso mejor lo comprobaremos en otra ocasión.

Resumen:

Si su servidor SMTP requiere autenticación para el envío de correo electrónico tendrá que establecer el valor de los siguientes Campos CDO:

"http://schemas.microsoft.com/cdo/configuration/sendusername" = Usuario
"http://schemas.microsoft.com/cdo/configuration/sendpassword" = Contraseña
"http://schemas.microsoft.com/cdo/configuration/smtpauthenticate" = 1 'Basic

Para ello tiene que adjuntarlos a la colección Fields de un objeto Configuration de CDO si está trabajando con el  Net Framework v.1.0, o bien agregarlos al Diccionario Fields de System.Web.Mail.MailMessage si está trabajando con el .Net Framework v.1.1.

posted on Wednesday, September 01, 2004 2:14 AM by vbpuntonet





Powered by Dot Net Junkies, by Telligent Systems