c# exchange-server office365 sendmail system.net.mail

c# - Enviar correo electrónico SMTP usando System.Net.Mail a través de Exchange Online(Office 365)



exchange-server office365 (7)

¿Has visto esto? Envío de correo electrónico utilizando Smtp.mail.microsoftonline.com

El establecimiento de UseDefaultCredentials después de configurar las credenciales estaría restableciendo su propiedad de credenciales.

Estamos probando la nueva versión beta de Office 365 y tengo una cuenta de correo en el servicio Exchange Online. Ahora estoy intentando conectar una aplicación LOB que puede enviar correos electrónicos smtp desde mi cuenta de prueba.

Sin embargo, la plataforma Exchange 365 requiere cifrado TLS en el puerto 587, y hay una ''característica'' de System.Net.Mail que no permite el cifrado SSL implícito.

¿Alguien ha logrado que C # envíe correos a través de esta plataforma?

Tengo el siguiente código básico que debe enviar el correo: cualquier consejo sería apreciado.

SmtpClient server = new SmtpClient("ServerAddress"); server.Port = 587; server.EnableSsl = true; server.Credentials = new System.Net.NetworkCredential("[email protected]", "password"); server.Timeout = 5000; server.UseDefaultCredentials = false; MailMessage mail = new MailMessage(); mail.From = new MailAddress("recipent@anyaddress"); mail.To.Add("[email protected]"); mail.Subject = "test out message sending"; mail.Body = "this is my message body"; mail.IsBodyHtml = true; server.Send(mail);


Aquí hay una nota al margen para algunos que pueden estar buscando en este hilo una respuesta a este problema. (Asegúrese de leer las precauciones en la parte inferior antes de implementar esta solución.) Tenía problemas para enviar correos electrónicos a un cliente para el cual mi suscripción a MS Office 365 no tenía un usuario o dominio. Intentaba SMTP a través de mi cuenta [email protected] 365, pero el mensaje de correo .NET se dirigió desde [email protected] . Esto es cuando el error "5.7.1 El cliente no tiene permisos" apareció para mí. Para remediarlo, la clase MailMessage necesitaba tener la propiedad Sender configurada en una dirección de correo electrónico que mis credenciales SMTP provistas tenían permiso en O365 para "Enviar como". Elegí usar el correo electrónico de mi cuenta principal ( [email protected] ) como se ve en el código a continuación. Tenga en cuenta que podría haber usado CUALQUIER dirección de correo electrónico que mi cuenta O365 tenga permiso para "enviar como" (es decir, [email protected], no-replicació[email protected], etc.)

using System; using System.Net.Mail; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { using ( MailMessage message = new MailMessage { To = { new MailAddress("[email protected]", "Recipient 1") }, Sender = new MailAddress("[email protected]", "Me"), From = new MailAddress("[email protected]", "Client"), Subject=".net Testing" Body="Testing .net emailing", IsBodyHtml=true, } ) { using ( SmtpClient smtp = new SmtpClient { Host = "smtp.office365.com", Port = 587, Credentials = new System.Net.NetworkCredential("[email protected]", "Pa55w0rd"), EnableSsl = true } ) { try { smtp.Send(message); } catch (Exception excp) { Console.Write(excp.Message); Console.ReadKey(); } } } } } }

Tenga en cuenta que SmtpClient solo es desechable y puede usar el bloque Using en .NET Framework 4
Los usuarios de .NET Framework 2 a 3.5 deben usar SmtpClient como tal ...

SmtpClient smtp = new SmtpClient { Host = "smtp.office365.com", Port = 587, Credentials = new System.Net.NetworkCredential("[email protected]", "Pa55w0rd"), EnableSsl = true }; try { smtp.Send(message); } catch (Exception excp) { Console.Write(excp.Message); Console.ReadKey(); }

El encabezado del correo electrónico resultante se verá más o menos así:

Authentication-Results: spf=none (sender IP is ) [email protected]; Received: from MyPC (192.168.1.1) by BLUPR13MB0036.namprd13.prod.outlook.com (10.161.123.150) with Microsoft SMTP Server (TLS) id 15.1.318.9; Mon, 9 Nov 2015 16:06:58 +0000 MIME-Version: 1.0 From: Client <[email protected]> Sender: Me <[email protected]> To: Recipient 1 <[email protected]>

-- Ser cauteloso --
Tenga en cuenta que algunos clientes de correo pueden mostrar la dirección del remitente como una nota. Por ejemplo, Outlook mostrará algo en esta línea en el encabezado del panel de lectura:

Me <[email protected]> en nombre del cliente <[email protected]>

Sin embargo, siempre que el cliente de correo electrónico que utiliza el destinatario no sea una basura total, esto no debería afectar a la dirección Responder a. Reply To aún debe usar la dirección From. Para cubrir todas sus bases, también puede utilizar la propiedad MailMessage.ReplyToList para brindarle al cliente la oportunidad de usar la dirección de respuesta correcta.

Además, tenga en cuenta que algunos servidores de correo electrónico pueden descartar cualquier correo electrónico que se envíe en nombre de otra empresa que establezca Restricciones de política del propietario del dominio. Asegúrese de realizar una prueba exhaustiva y buscar cualquier rebote. Puedo decirle que mi cuenta de correo electrónico personal de Hotmail (mail.live.com) rechaza los mensajes que envío en nombre de cierto cliente mío, pero otros clientes pasan bien. Aunque sospecho que tiene algo que ver con los registros TXT "spf1" del dominio de mi cliente, no tengo una respuesta sobre por qué rechazará los correos electrónicos enviados en nombre de un dominio frente a otro. Tal vez alguien que sabe puede arrojar algo de luz sobre el tema?


Finalmente, funciona!

Ponga smtpClient.UseDefaultCredentials = false; después de smtpClient.Credentials = credentials; entonces problema resuelto!

SmtpClient smtpClient = new SmtpClient(smtpServerName); System.Net.NetworkCredential credentials = new System.Net.NetworkCredential(smtpUName, smtpUNamePwd); smtpClient.Credentials = credentials; smtpClient.UseDefaultCredentials = false; <-- Set This Line After Credentials smtpClient.Send(mailMsg); smtpClient = null; mailMsg.Dispose();


He portado el código c # utilizado para trabajar contra smtp.google.com:587 para trabajar a través de office365 sin éxito. Intenté todas las combinaciones de Credencial antes / después de usar Ssl y casi todas las recomendaciones hechas en Internet - sin éxito (se obtuvo 5.7.1 .... error).

Finalmente obtuve esta línea de algún lugar como último recurso, justo antes. Enviar (mensaje)

smtpClient.TargetName = "STARTTLS/smtp.office365.com";

Desde entonces, cada envío () es un gran éxito.


Office 365 utiliza dos servidores, el servidor smtp y protege el servidor extendido.

El primer servidor es smtp.office365.com (propiedad Host del cliente smtp) y el segundo servidor es STARTTLS / smtp.office365.com (propiedad TargetName del cliente smtp). Otra cosa es debe poner Usedefaultcredential = false antes de establecer las credenciales de red.

client.UseDefaultCredentials = False client.Credentials = New NetworkCredential("[email protected]", "Password") client.Host = "smtp.office365.com" client.EnableSsl = true client.TargetName = "STARTTLS/smtp.office365.com" client.Port = 587 client.Send(mail)


Respuesta rápida: la dirección FROM debe coincidir exactamente con la cuenta desde la que está enviando, o obtendrá un error 5.7.1 El cliente no tiene permisos para enviar como este remitente.

Supongo que eso impide que se falsifique el correo electrónico con su cuenta de Office 365; de lo contrario, es posible que pueda enviarlo como [email protected].

Otra cosa que debes probar es la autenticación, completa el tercer campo con el dominio, como

Dim smtpAuth = New System.Net.NetworkCredential( "TheDude", "hunter2password", "MicrosoftOffice365Domain.com")

Si eso no funciona, compruebe que puede iniciar sesión en la cuenta en: https://portal.microsoftonline.com

Otra cosa a tener en cuenta es que su solución antivirus puede estar bloqueando el acceso programático a los puertos 25 y 587 como una solución antispam. Norton y McAfee pueden bloquear en silencio el acceso a estos puertos. Solo habilitando la depuración de Correo y Socket le permitirá notarlo (ver a continuación).

Una última cosa a tener en cuenta, el método de envío es asincrónico . Si llamas

Dispose inmediatamente después de llamar al envío, es muy probable que cierre su conexión antes de que se envíe el correo. Haga que su instancia de smtpClient escuche el evento OnSendCompleted y haga una llamada desde allí. En su lugar, debe usar el método SendAsync, el método Send no genera este evento.

Respuesta detallada: con Visual Studio (VB.NET o C # no importa), hice un formulario simple con un botón que creaba el Mensaje de Correo, similar al anterior. Luego agregué esto a la application.exe.config (en el directorio bin / debug de mi proyecto). Esto permite que la pestaña Salida tenga información detallada sobre la depuración.

<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <sources> <source name="System.Net"> <listeners> <add name="System.Net" /> </listeners> </source> <source name="System.Net.Sockets"> <listeners> <add name="System.Net" /> </listeners> </source> </sources> <switches> <add name="System.Net" value="Verbose" /> <add name="System.Net.Sockets" value="Verbose" /> </switches> <sharedListeners> <add name="System.Net" type="System.Diagnostics.TextWriterTraceListener" initializeData="System.Net.log" /> </sharedListeners> <trace autoflush="true" /> </system.diagnostics> </configuration>


Se corrigieron algunos errores tipográficos en el código de trabajo anterior:

MailMessage msg = new MailMessage(); msg.To.Add(new MailAddress("[email protected]", "SomeOne")); msg.From = new MailAddress("[email protected]", "You"); msg.Subject = "This is a Test Mail"; msg.Body = "This is a test message using Exchange OnLine"; msg.IsBodyHtml = true; SmtpClient client = new SmtpClient(); client.UseDefaultCredentials = false; client.Credentials = new System.Net.NetworkCredential("your user name", "your password"); client.Port = 587; // You can use Port 25 if 587 is blocked (mine is!) client.Host = "smtp.office365.com"; client.DeliveryMethod = SmtpDeliveryMethod.Network; client.EnableSsl = true; try { client.Send(msg); lblText.Text = "Message Sent Succesfully"; } catch (Exception ex) { lblText.Text = ex.ToString(); }

Tengo dos aplicaciones web que usan el código anterior y ambas funcionan bien sin ningún problema.