LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

MailMessage保存为eml文件(C#+SmtpClient)

admin
2017年11月7日 16:56 本文热度 7224
.NET 自从2.0开始,大大提升了 Mail.SmtpClient 的功能,对于发邮件,可谓游刃有余了。但是,美中不足的是没有提供保存邮件内容为eml文件的功能。

实际上,SmtpClient 和 MailMessage 已经实现了这个功能,只是这个功能是 NonPublic 的,对于空间外,不可见而已。

利用 Reflector 反编译一下 System.Net.Mail.SmtpClient 可以看到:

SmtpClient.Send

 

在 Send(MailMessage) 方法中,在MAIL被发送之前,是调用了一个 MailWriter fileMailWriter = this.GetFileMailWriter(this.PickupDirectoryLocation);

我们顺藤摸瓜,继续定位 GetFileMailWriter 这个方法

System.Net.Mail.MailWriter

上面的代码中,赫然醒目的显示着 .eml ,看了里面的逻辑,我们其实就清楚了,SmtpClient.Send 之前,也是先生成了一个临时的eml文件,然后再发送这个文件出去的。

其中的关键就在 new MailWriter(new FileStream(str2, FileMode.CreateNew)) 这里。

我们接下来定位到我们的核心 MailWriter :

SmtpClient.Send

从上面可以看到,MailWriter 是一个 internal 的 class,所以我们在普通的调用Mail.SmtpClient 等的命名空间下,是看不到的,这时我们就需要用到反射(Reflection) 了。

下面给出完整的实现代码:

using System;
using ADODB;
using CDO;
using System.Net.Mail;
using System.IO;
using System.Globalization;
using System.Reflection;

    /// <summary>
    /// 将MailMessage保存为eml文件
    /// </summary>
    /// <param name="msg">待保存的具有内容的MailMessage</param>
    /// <param name="emlFileAbsolutePath">保存后的eml文件的路径</param>

    static void SaveToEml(MailMessage msg, string emlFileAbsolutePath)
    {
        const BindingFlags flags = BindingFlags.Instance │ BindingFlags.NonPublic │ BindingFlags.FlattenHierarchy;
        using (MemoryStream ms = new MemoryStream())
        {
            Assembly assembly = typeof(System.Net.Mail.SmtpClient).Assembly;
            Type tMailWriter = assembly.GetType("System.Net.Mail.MailWriter");
            object mailWriter = Activator.CreateInstance(tMailWriter, flags, null, new object[] { ms }, CultureInfo.InvariantCulture);
            msg.GetType().GetMethod("Send", flags).Invoke(msg, new object[] { mailWriter, true });
            File.WriteAllText(emlFileAbsolutePath, System.Text.Encoding.Default.GetString(ms.ToArray()), System.Text.Encoding.Default);
        }
    }

使用方法:

MailMessage msg = new MailMessage();
msg.Subject = "你好,我是点晴";
msg.From = new MailAddress("cs@clicksun.cn");
msg.To.Add("service@clicksun.cn");
msg.Body = "欢迎访问点晴官网:";
SaveToEml(msg, @"d:\test.eml");

好了 ,完结了,祝大家好运吧!


该文章在 2017/11/7 17:23:46 编辑过

全部评论1

admin
2017年11月7日 23:41

C#将MailMessage保存为本地eml文件续(.Net+SmtpClient)

在上一篇 MailMessage保存为eml文件(C#+SmtpClient) 中,我们使用了反射(Reflection)的方式,调用System.Net.Mail的内部对象 MailWriter 实现了将 MailMessage 的内容保存为 eml 文件。

通过上次的实现,主要是学习反射Reflection的使用思路,起到个抛砖引玉的作用吧。今天,偶尔看到了上次的代码,又重新发现了一个新大陆,使得保存eml文件的工作,变得异常简单了。

.NET 的 SmtpClient 对于 DeliveryMethod 为 SpecifiedPickupDirectory PickupDirectoryFromIis 的情况,所做的只是 在特定的目录下,生成一个EML文件而已

对于 PickupDirectoryFromIis 的情况,需要IIS支持,不是我们要的,我们需要的,是SpecifiedPickupDirectory 这个。对于这种情况再简单不过了,实例代码如下:

SmtpClient smtp = new SmtpClient();
smtp.EnableSsl = false; //必须为 false
smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
smtp.PickupDirectoryLocation = @"d:\mail\"; //自定义目录
MailMessage msg = new MailMessage();
msg.Subject = "hello, i am deltacat";
msg.From = new MailAddress("deltacat@microsoft.com");
msg.To.Add("zu14.cn@live.cn");
msg.Body = "welcome to www.zu14.cn";
smtp.Send(msg);

上面的方式,根本不需要配置 smtp 服务器等等的,很是方便;缺点是生成的EML文件名,是一个GUID,不能自己控制。

好了,就写这些,希望对大家有帮助吧


该评论在 2017/11/7 23:43:32 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved