如何在附件中发送html?

时间:2011-08-29 10:49:57

标签: c# email

我需要通过电子邮件发送一些html文本。但我需要不是在电子邮件正文中,而是在附件中。我使用此代码段来形成附件:

public MailMessage GetMailMessage(string @from)
{
  var m = new MailMessage(new MailAddress(@from), new MailAddress(_to)) {Subject = _subj};
  var attach = new Attachment(new MemoryStream(
       Encoding.UTF8.GetBytes(_htmlAttach)), _subj + ".html", MediaTypeNames.Text.Html);
  attach.ContentDisposition.Inline = false;
  attach.ContentType.Name = _subj + ".html";
  m.Attachments.Add(attach);
  return m;
}

但是当我将这样的电子邮件发送到我的Gmail邮箱时,我收到了一条纯文字信息,上面写着这样的文字:

\ =?utf-8?B?dDlDd0lOQy8wTFhSZ05DNDBMN1F0Q0F4Pz0NCiA9P3V0Zi04P0I/TXpv?=\ \ =?utf-
8?B?ME5pQXlPUzR3T0M0eU1ERXhJQzBnTVRRNk1qQWdNamt1TURndU1qQXhN?=\ \ =?utf-8?B?UzVvZEcxcz89?=" 
Content-Transfer-Encoding: base64 Content-Disposition: attachment 
PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEvL0VO 
IiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvc3RyaWN0LmR0ZCI+DQo8aHRt 
bCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgeG1sOmxhbmc9 ImVuIj4NCjxoZWFkPg0KI

在附件中发送html文件的正确方法是什么?


UPD:这是原始邮件消息部分:

MIME-Version: 1.0
From: <xxx@xxx.xx>
To: xxx@gmail.com
Date: Mon, 29 Aug 2011 03:29:05 -0700 (PDT)
Subject: xxx
Content-Type: multipart/mixed; boundary=--boundary_0_c99e5172-1766-4cfe-a6e0-7f6b0fa11061
----boundary_0_c99e5172-1766-4cfe-a6e0-7f6b0fa11061
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: quoted-printable


----boundary_0_c99e5172-1766-4cfe-a6e0-7f6b0fa11061
Content-Type: text/html;
name="=?utf-8?B?PT91dGYtOD9CPzBLUFFzdEMxMExUUXZ0QzgwTHZRdGRDOTBMalF0U0RR?=\
\

 =?utf-8?B?dDlDd0lOQy8wTFhSZ05DNDBMN1F0Q0F4Pz0NCiA9P3V0Zi04P0I/TXpv?=\
\

 =?utf-8?B?ME5pQXlPUzR3T0M0eU1ERXhJQzBnTVRRNk1qQWdNamt1TURndU1qQXhN?=\
\
 =?utf-8?B?UzVvZEcxcz89?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment

然后转到base64文本:

PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEvL0VO
IiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvc3RyaWN0LmR0ZCI+DQo8aHRt
bCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgeG1sOmxhbmc9
ImVuIj4NCjxoZWFkPg0KICAgIDxtZXRhIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hh

最后:

----boundary_0_c99e5172-1766-4cfe-a6e0-7f6b0fa11061--

4 个答案:

答案 0 :(得分:1)

看起来您在生成的部分之间缺少换行符。所以你需要输入类似"To: " + newMailAddress(to) + "\n"等的东西。你还需要构建容器MIME结构。如果您没有任何实际消息,只需将HTML作为单个正文部分发送,而不是作为“附件”发送。像这样的东西

From: me <self@example.net>
To: you <guy@example.com>
Subject: here
MIME-Version: 1.0
Content-type: text/html; name="=?utf-8?q?really_bewildering?=
  =?utf-8?q?_long_name.html?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="=?utf-8?q?really_bewildering?=
  =?utf-8?q?_long_name.html?="

PCFET0NUWVBFIGh0bWwgUFVCTElDICItL ...

您粘贴的示例消息(将其移动包裹在单部分多部分/相关结构中)完全等效。

我相信在Content-Disposition中的文件名=部分是放置文件名的正确位置,但为了向后兼容非常老的客户,你最好把它放在两个地方。

请注意包装长标题行的正确方法:换行符之前不应有反斜杠;相反,用至少一个空白字符缩进后续行。标题中应该没有空行(空行是将标题与正文分隔开来的;因此错误标题中的第一个空行是将其余标题推入正文中。)

到处都有base64编码?除非您的文档对8位内容很重,否则如果使用quoted-printable,它可能更小,更容易调试。您会注意到我将文件名更改为quoted-printable只是为了更容易阅读;您也可以对实际附件的内容做同样的事情。

更新:添加了内容处理和文件名以及示例邮件下方的评论。

强调:当前的问题是您在MIME标头中错误地包装了多行文件名。

答案 1 :(得分:0)

而不是将字节放入内存流中,为什么不放入文本?

我认为你可以使用new Attachment()的另一个重载并以另一种方式指定内容。

如果您已将某个文件存储在某处,则可以附加该文件,或者您可以使用StreamReader / TextReader组合来确保将文本数据而非二进制数据推送到attachmentz内容中。

答案 2 :(得分:0)

使用SevenBit(最多1000个字符!)或QuotedPrintable作为TransferEncoding附件。

答案 3 :(得分:0)

您的附件类型很时髦。对于只想发送UTF8(标准文本)的用户,必须指定附件内容类型。这需要一个Stream来输入,而不是传递字符串。

示例,其中包含html文本列表

System.Net.Mime.ContentType ct 
            = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Text.Html);

HtmlAttachments.Select( str => new Attachment(str.ToStream(), ct))
               .ToList()
               .ForEach( html => mailMessage.Attachments.Add(html));

... {Usual loading of to/from etc }

client.Send(mailMessage);

为完整起见,这里是ToStream extensions

public static Stream ToStream( this string value ) => ToStream(value, Encoding.UTF8);

public static Stream ToStream( this string value, Encoding encoding )
                        => new MemoryStream(encoding.GetBytes(value ?? string.Empty));