我目前正在考虑在C#中序列化一个MailMessage对象,尽管网上有一些示例的变体,但它们会序列化为二进制,这种错过IMO的点。
我的方法是,我想将MailMessage序列化为RFC2822 eml字符串,下面的代码就是我提出来的。
public string SerializeEmail(MailMessageArgs e)
{
string rfc822eml = "";
Guid g = Guid.NewGuid();
lock (g.ToString())
{
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(@"C:\tmpspool");
di.CreateSubdirectory(g.ToString());
string spoolDir = @"C:\tmpspool\" + g.ToString();
SmtpClient Client = new SmtpClient("localhost");
Client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
Client.PickupDirectoryLocation = spoolDir;
Client.Send(e.mailObj);
var files = from file in Directory.EnumerateFiles(spoolDir)
select file;
string serializedEml = files.First();
rfc822eml = File.ReadAllText(serializedEml);
File.Delete(serializedEml);
Directory.Delete(spoolDir);
}
return rfc822eml;
}
这很糟糕但它确实有用。理想情况下,我会创建一个新的SMTPClient并添加一个Serialize函数,该函数将自动返回rfc822字符串,而不会触及文件系统。
由于我似乎无法使用Visual Studio跟踪SMTPClient.Send函数,因此这种“理想”的处理方式有点棘手。
我已经通过在Peter Huber的POP3MimeClient和POP3MailClient类中添加一些小的更改来整理RFC消息的反序列化,这样我就可以将HDD上的文件或字符串反序列化为MailMessage。
对我唠叨的是,我真的应该能够使用流序列化MailMessaage并将流写入我选择的字符串 - 或 - 文件而不是围绕房屋创建基于GUID的文件夹作为上面的代码执行并将文件的内容读回字符串...
任何关于如何让这更优雅的指示将非常感激。
感谢。
答案 0 :(得分:19)
这将是一个黑客。不要忘记,MS可以在.Net的下一个版本中更改它。
(在ILSpy的帮助下)你可以编写如下的扩展方法
public static class MailExtensions
{
public static string ToEml(this MailMessage mail)
{
var stream = new MemoryStream();
var mailWriterType = mail.GetType().Assembly.GetType("System.Net.Mail.MailWriter");
var mailWriter = Activator.CreateInstance(
type: mailWriterType,
bindingAttr: BindingFlags.Instance | BindingFlags.NonPublic,
binder: null,
args: new object[] { stream },
culture: null,
activationAttributes: null);
mail.GetType().InvokeMember(
name: "Send",
invokeAttr: BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
binder: null,
target: mail,
args: new object[] { mailWriter, true, true });
return Encoding.UTF8.GetString(stream.ToArray());
}
}
并用作
string eml = mailMessage.ToEml();
答案 1 :(得分:0)
经过大量工作后,我终于设法反序列化了MailMessage:
为了做到这一点,我创建了一个将在客户端应用程序和Web服务中使用的DLL。这需要与反序列化相同:)
我在这里选择了dll序列化类:https://bitbucket.org/burningice/compositec1contrib.email/src/0bba07df532c8134717cfb40757f4cb22f002b1d/Email/Serialization/?at=default
非常感谢分享!
编译完成后,将新的dll添加到项目中,发送和接收工作正常。
所以我用这种方式转换MailMessage:string serializedMessage = SerializeAsBase64(mail); 在Webservice中,我用这种方式重建它: MailMessage Mm = DeserializeFromBase64(serializedMessage);
我希望这会有所帮助......