我需要通过电子邮件发送一些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--
答案 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));