example body c# .net-4.5

body - send email c# gmail



Obtención de System.Net.Mail.MailMessage como MemoryStream en.NET 4.5 beta (4)

Esto podría ser útil si no quieres ir con hacks no compatibles y no te importa un rendimiento extra.

public static class MailMessageExtensions { public static string RawMessage(this MailMessage m) { var smtpClient = new SmtpClient { DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory }; using (var tempDir = new TemporaryDirectory()) { smtpClient.PickupDirectoryLocation = tempDir.DirectoryPath; smtpClient.Send( m ); var emlFile = Directory.GetFiles( smtpClient.PickupDirectoryLocation ).FirstOrDefault(); if ( emlFile != null ) { return File.ReadAllText( emlFile ); } else return null; } return null; } } class TemporaryDirectory : IDisposable { public TemporaryDirectory() { DirectoryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory( DirectoryPath ); } public string DirectoryPath { get; private set; } public void Dispose() { if ( Directory.Exists( DirectoryPath ) ) Directory.Delete( DirectoryPath, true ); } }

Por lo tanto, el siguiente código se utiliza para trabajar en .NET 4 para obtener un objeto System.Net.Mail.MailMessage como MemoryStream, sin embargo, con el lanzamiento de .NET 4.5 beta se produce una excepción en tiempo de ejecución.

Assembly assembly = typeof(SmtpClient).Assembly; Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter"); using (MemoryStream stream = new MemoryStream()) { ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null); object mailWriter = mailWriterContructor.Invoke(new object[] { stream }); MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic); sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true }, null); ..... }

La excepción de tiempo de ejecución se produce en sendMethod.Invoke ().


La solución propuesta con el TRUE extra funciona a la perfección.

Comencé a recibir el error mientras ejecutaba mi proyecto en VS2012 aunque no estoy usando .net 4.5 sino 4.0 en todas mis bibliotecas.

El error solo ocurre en la máquina donde instaló VS2012, parece que VS2012 hace referencia a .net 4.5 mientras realiza la depuración. Cuando implementa y ejecuta la aplicación en clientes que ejecutan .net 4.0, todo funciona bien.

Por lo tanto: si ejecuta 4.0, no agregue TRUE extra, si ejecuta 4.5, añádalo.


Se las arregló para descubrir cómo hacer que esto vuelva a funcionar en .NET 4.5 beta. El método de la API privada Send () en MailMessage ha cambiado a: envío interno no válido (escritor BaseWriter, bool sendEnvelope, bool allowUnicode)

Por favor encuentre el código actualizado a continuación.

Assembly assembly = typeof(SmtpClient).Assembly; Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter"); using (MemoryStream stream = new MemoryStream()) { ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null); object mailWriter = mailWriterContructor.Invoke(new object[] { stream }); MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic); sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true, true }, null); ..... }


para comprobar si extra booleano uso:

If _sendMethod.GetParameters.Length = 2 Then _sendMethod.Invoke(Message, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Object() {_mailWriter, True}, Nothing) Else _sendMethod.Invoke(Message, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Object() {_mailWriter, True, True}, Nothing) End If