将电子邮件保存到具有指定文件名的目录在 .NET 5.0 中不起作用
Saving email to the directory with specified file name is not working in .NET 5.0
我正在尝试遵循 Allan Eagle 在代码项目中 post 中建议的方法。这种相同的方法在 .NET Core 3.1
之前一直运行良好,但不适用于 .NET 5.0
。这是我创建的保存方法,
private void Save(MailMessage message, string filePath)
{
var assembly = typeof(SmtpClient).Assembly;
var mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
var mailWriterContructor = mailWriterType.GetConstructors(bindingFlags)[0];
var mailWriter = mailWriterContructor.Invoke(new object[] { fileStream });//<-- This line throws error saying parameter mismatch
var sendMethod = typeof(MailMessage).GetMethod("Send", bindingFlags);
sendMethod.Invoke(message, bindingFlags, null, new[] { mailWriter, true, true }, null);
var closeMethod = mailWriter.GetType().GetMethod("Close", bindingFlags);
closeMethod.Invoke(mailWriter, bindingFlags, null, new object[] { }, null);
}
}
我检查了所有可用的底层调用方法并尝试使用它们传递所需的参数,但没有一个对我有用。
错误消息:“参数计数不匹配。”
内部异常:null
堆栈跟踪:
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
at..//user written line info
任何解决此问题的帮助或使用 System.Net.Mail
实现相同目的的新方法将不胜感激。
正如我在评论中提到的,这篇文章在 2020 年已过时。尽管有日期,它实际上是在 2009 年编写的,并在 2014 年停止工作,当时一些内部方法更改了签名。在任何情况下,都不应该使用 System.Net.Mail
命名空间,因为正如 Microsoft 强烈警告的那样:
Important
We don't recommend that you use the SmtpClient class for new development because SmtpClient doesn't support many modern protocols. Use MailKit or other libraries instead. For more information, see SmtpClient shouldn't be used on GitHub.
MailKit(或者更确切地说,它所构建的 MimeKit 库)已经支持保存和加载邮件消息。来自 Q: How do I save messages? 的答案很简单:
message.WriteTo("message.eml");
您可以使用 MailKit 的 POP3 或 IMAP4 客户端来检索邮件。 DownloadMessages 示例展示了如何从 GMail 下载邮件并保存它们:
using (var client = new Pop3Client (new ProtocolLogger ("pop3.log"))) {
client.Connect ("pop.gmail.com", 995, SecureSocketOptions.SslOnConnect);
client.Authenticate ("username", "password");
for (int i = 0; i < client.Count; i++) {
var message = client.GetMessage (i);
// write the message to a file
message.WriteTo (string.Format ("{0}.msg", i));
// mark the message for deletion
client.DeleteMessage (i);
}
client.Disconnect (true);
}
要根据第一条评论明确给您答案,
var encodeForTransport = false;
var mailWriter = mailWriterContructor.Invoke(new object[] { fileStream, encodeForTransport });
我正在尝试遵循 Allan Eagle 在代码项目中 post 中建议的方法。这种相同的方法在 .NET Core 3.1
之前一直运行良好,但不适用于 .NET 5.0
。这是我创建的保存方法,
private void Save(MailMessage message, string filePath)
{
var assembly = typeof(SmtpClient).Assembly;
var mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
var mailWriterContructor = mailWriterType.GetConstructors(bindingFlags)[0];
var mailWriter = mailWriterContructor.Invoke(new object[] { fileStream });//<-- This line throws error saying parameter mismatch
var sendMethod = typeof(MailMessage).GetMethod("Send", bindingFlags);
sendMethod.Invoke(message, bindingFlags, null, new[] { mailWriter, true, true }, null);
var closeMethod = mailWriter.GetType().GetMethod("Close", bindingFlags);
closeMethod.Invoke(mailWriter, bindingFlags, null, new object[] { }, null);
}
}
我检查了所有可用的底层调用方法并尝试使用它们传递所需的参数,但没有一个对我有用。
错误消息:“参数计数不匹配。”
内部异常:null
堆栈跟踪:
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
at..//user written line info
任何解决此问题的帮助或使用 System.Net.Mail
实现相同目的的新方法将不胜感激。
正如我在评论中提到的,这篇文章在 2020 年已过时。尽管有日期,它实际上是在 2009 年编写的,并在 2014 年停止工作,当时一些内部方法更改了签名。在任何情况下,都不应该使用 System.Net.Mail
命名空间,因为正如 Microsoft 强烈警告的那样:
Important
We don't recommend that you use the SmtpClient class for new development because SmtpClient doesn't support many modern protocols. Use MailKit or other libraries instead. For more information, see SmtpClient shouldn't be used on GitHub.
MailKit(或者更确切地说,它所构建的 MimeKit 库)已经支持保存和加载邮件消息。来自 Q: How do I save messages? 的答案很简单:
message.WriteTo("message.eml");
您可以使用 MailKit 的 POP3 或 IMAP4 客户端来检索邮件。 DownloadMessages 示例展示了如何从 GMail 下载邮件并保存它们:
using (var client = new Pop3Client (new ProtocolLogger ("pop3.log"))) {
client.Connect ("pop.gmail.com", 995, SecureSocketOptions.SslOnConnect);
client.Authenticate ("username", "password");
for (int i = 0; i < client.Count; i++) {
var message = client.GetMessage (i);
// write the message to a file
message.WriteTo (string.Format ("{0}.msg", i));
// mark the message for deletion
client.DeleteMessage (i);
}
client.Disconnect (true);
}
要根据第一条评论明确给您答案,
var encodeForTransport = false;
var mailWriter = mailWriterContructor.Invoke(new object[] { fileStream, encodeForTransport });