将System.Net.Mail.MailMessage作为.NET 4.5 beta版的MemoryStream

因此,下面的代码用于在.NET 4中工作以将System.Net.Mail.MailMessage对象作为MemoryStream获取,但是随着.NET 4.5 beta的发布,发生了运行时exception。

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); ..... } 

sendMethod.Invoke()上发生运行时exception。

管理如何在.NET 4.5 beta中再次使用它。 MailMessage中的私有API Send()方法已更改为:internal void Send(BaseWriter writer,bool sendEnvelope,bool allowUnicode)

请在下面找到更新的代码。

 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); ..... } 

如果您不想使用不受支持的黑客并且不介意额外的性能损失,这可能是有用的。

 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 ); } } 

检查我是否使用额外的布尔值:

  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 

带有额外TRUE的建议解决方案非常有效。

我在VS2012中运行我的项目时开始出错,即使我在我的所有库中都没有使用.net 4.5但是4.0。

该错误仅发生在已安装VS2012的计算机上,看起来VS2012在您调试时引用了.net 4.5。 在运行.net 4.0的客户端中部署和运行应用程序时,一切正常。

因此:如果你运行4.0 – 不要添加额外的TRUE,如果你运行4.5添加它。