在.NET中序列化MailMessage对象的优雅方法 [英] Elegant way to serialize a MailMessage object in .NET

查看:157
本文介绍了在.NET中序列化MailMessage对象的优雅方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用C#序列化MailMessage对象,尽管网络上的示例有多种变体,但它们序列化为二进制格式,从而错过了IMO点.

I'm currently looking at serializing a MailMessage object in C# and although there are a couple of variations of an example on the net, they serialize to binary which kind of misses the point IMO.

我的方法是,我想将MailMessage序列化为RFC2822 eml字符串,下面的代码就是我想出的.

My approach is that I'd like to serialize a MailMessage to an RFC2822 eml string and the code below is what I've come up with.

    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字符串而不会触及文件系统.

It's pretty nasty but it does work. Ideally though, I'd create a new SMTPClient and add in a Serialize function which would return the rfc822 string automatically without it ever hitting the file system.

由于我似乎无法使用Visual Studio跟踪SMTPClient.Send函数,因此这种理想"的处理方式有些棘手.

As I don't seem to be able to trace into the SMTPClient.Send function with Visual Studio, this "ideal" way of doing things is a tad tricky.

我已经通过对Peter Huber的POP3MimeClient和POP3MailClient类进行一些小的更改来解决RFC消息的反序列化问题,以便可以将HDD上的文件反序列化或将字符串反序列化为MailMessage.

I've already sorted out the deserialization of the RFC message by adding in some small changes to Peter Huber's POP3MimeClient and POP3MailClient classes so I can deserialize a file on the HDD or a string back into a MailMessage.

困扰我的是,我真的应该能够使用流序列化MailMessaage并将流写入我选择的字符串-或-文件,而不是四处走动以创建基于GUID的文件夹作为上面的代码可以将文件内容读回到字符串中...

The thing that's nagging at me is that I really should be able to serialize the MailMessaage using a stream and writing the stream to a string -or- file of my choice instead of going around the houses to create GUID based folders as the code above does and reading the content of the file back into a string...

任何有关如何使它变得更加优雅的指针将不胜感激.

Any pointers as to how I could make this more elegant will be much appreciated.

谢谢.

推荐答案

这将是一个hack.别忘了,MS可以在.Net的下一版本中对其进行更改.

(借助ILSpy),您可以编写如下扩展方法

(With the help of ILSpy) you can write an extension method like below

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

这篇关于在.NET中序列化MailMessage对象的优雅方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆