如何在附件中发送html?
Posted
技术标签:
【中文标题】如何在附件中发送html?【英文标题】:How to send html in attachment? 【发布时间】:2011-11-05 22:40:43 【问题描述】:我需要通过电子邮件发送一些 html 文本。但我不需要在电子邮件正文中而是在附件中这样做。我用这段代码 sn-p 形成一个附件:
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--
【问题讨论】:
文件名看起来不对。 “Content-Type: text/html;”之后真的有换行符吗?还有样本中的反斜杠,它们是字面的吗?他们不应该在那里。反斜杠后的换行符也是如此。最后,文件名看起来像是经过了多次 RFC2047 编码;第一个短语解码为以=?utf-8?B?...
开头的内容
这是解码文件名:=?utf-8?B?0KPQstC10LTQvtC80LvQtdC90LjQtSDQt9CwINC/0LXRgNC40L7QtCAx?= =?utf-8?B?Mzo0NiAyOS4wOC4yMDExIC0gMTQ6MjAgMjkuMDguMjAxMS5odG1s?=
(原文如此!)解码反过来产生Уведомление за период 13:46 29.08.2011 - 14:20 29.08.2011.html
。你至少应该去掉双重编码。
【参考方案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 中的 filename= 部分是放置文件名的正确位置,但为了与非常旧的客户端向后兼容,最好将其放在两个位置。
注意包装长标题行的正确方法:换行之前不应有反斜杠;而是用至少一个空格字符缩进后续行。标题中不应有空行(空行是将标题与正文分开;因此错误标题中的第一个空行是将其余标题推入正文)。
base64 编码无处不在是怎么回事?除非您的文档包含大量 8 位内容,否则如果您改用quoted-printable,它可能更小且更易于调试。您会注意到我将文件名更改为quoted-printable 只是为了更易于阅读;你也可以对实际附件的内容做同样的事情。
更新:在示例消息下方添加了 Content-Disposition 和文件名以及 cmets。
重点:直接的问题是您在 MIME 标头中的多行文件名换行不正确。
【讨论】:
查看原始电子邮件,有换行符。我需要在附件中发送一个 html,因为它可能非常大。 添加更多的 MIME 结构会使消息更大,而不是更小。您在问题中粘贴的内容显然缺少标题和换行符;也许您需要使用\r\n
而不仅仅是\n
(SMTP 需要 DOS 样式的行尾,但许多 MTA 将接受平台原生行尾约定的输入)。
实际上文件名应该按照RFC5987 正确编码,但这是切线的,所以我没有更新答案。另请参阅***.com/a/6745788/874188【参考方案2】:
与其将字节放入内存流,不如将文本放入?
我认为您可以使用 new Attachment()
的另一个重载并以另一种方式指定内容。
如果您已经将文件存储在某处,则可以附加该文件,或者您可以使用 StreamReader / TextReader 组合来确保将文本数据而不是二进制数据推送到附件内容中。
【讨论】:
我正在使用流,因为没有其他方法可以动态创建附件的内容。new Attachment()
的其他重载可以从文件中获取内容,而不是从字符串中获取。【参考方案3】:
附件使用SevenBit
(最多1000个字符!)或QuotedPrintable
作为TransferEncoding
。
【讨论】:
刚试过。我的电子邮件仍然没有附件,看起来像这样:\ =?utf- 8?B?dDlDd0lOQy8wTFhSZ05DNDBMN1F0Q0F4Pz0NCiA9P3 V0Zi04P0I/T0Rv?=\ \ =?utf-8?B?eU9DQXlOUzR3T0M0eU 1ERXhJQzBnTVRnNk1qZ2dNekF1TURndU1qQXhN?=\ \ =?utf- 8?B?UzVvZEcxcz89?=" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment =0D=0A=0D=0A=0D=0A =0D=0A= =0D=0A =0D=0A = =0D=0A=0D=0A =0D=0A =0D=0A =0D=0A =0D=0A = =0D=0A = =0D=0A
【参考方案4】:
您的附件类型很时髦。对于只想发送 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));
【讨论】:
以上是关于如何在附件中发送html?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ASP.NET 中使用具有 HTML 正文 + 附件的 GMAIL API 发送电子邮件
[单选题]如何将一个数组作为附件发送,并要能在接收后重新组合?
如何使用exchangelib在python中将熊猫数据框作为电子邮件附件发送
如何使用 JavaMail 发送带有附件的 html 电子邮件