使用 X-ALT-DESC / 将 HTML 应用于 Outlook 中的日历邀请
Using X-ALT-DESC / Applying HTML to calendar invites in Outlook
我是 C# 的初学者(老实说是任何网络代码)。我正在尝试发送日历邀请,当您单击公司网站上的按钮时,该邀请就会被发送。这是一个典型的n层系统,使用asp.net/C#和SQL。
我们过去只是简单地生成一个 ics,然后用户必须知道该 ics 才能使用 Outlook 打开,但从那以后我学会了如何手动编写 VCALENDAR 以便它立即在 Outlook 中漂亮整洁地显示出来。
一切都进行得相当顺利,但我现在希望日历邀请的正文能够接受 HTML,特别是附加链接。我已经尝试过 AlternateViews,但似乎 VCALENDAR 中的 "X-ALT-DESC" 属性应该完全符合我的要求。但是,尽我所能尝试 Outlook 忽略它并使用描述。显然我缺少一些东西。
(澄清一下,除了 HTML alt 描述外,一切正常并编译)
private Guid? CreateEmail()
{
Guid eventGuid = Guid.NewGuid();
MailMessage msg = new MailMessage();
msg.IsBodyHtml = true;
msg.From = new MailAddress("fromemail", "From Name");
msg.To.Add(toEmail);
msg.Subject = subject;
StringBuilder s = new StringBuilder();
s.AppendLine("BEGIN:VCALENDAR");
s.AppendLine("VERSION:2.0");
s.AppendLine("PRODID:-//My Product//Outlook MIMEDIR//EN");
s.AppendLine("METHOD:" + method); //In this case, "REQUEST"
s.AppendLine("STATUS:" + status.status); //"CONFIRMED"
s.AppendLine("BEGIN:VEVENT");
s.AppendLine("UID:" + eventGuid.ToString());
s.AppendLine("PRIORITY" + status.priority); //3
s.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:" + ShowAs.ToString()); //"BUSY"
s.AppendLine("SEQUENCE:" + UpdateNumber);//0
s.AppendLine("DTSTAMP:" + DateTime.Now.ToUniversalTime().ToString());
s.AppendLine("DTSTART:" + DateTimetoCalTime(startTime));
s.AppendLine("DTEND:" + DateTimetoCalTime(endTime));
s.AppendLine("SUMMARY:" + subject);
s.AppendLine("LOCATION: " + location);
s.AppendLine("DESCRIPTION: " + "Plain simple description"
string html_begin = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">" +
"\n<html>" +
"\n<head>" +
"\n<title></title>" +
"\n</head>" +
"\n<body>" +
"\n<!-- Converted from text/rtf format -->\n\n<P DIR=LTR><SPAN LANG=\"en-us\">" +
"\n<Font face=\"Times New Roman\"";
body = "I simply <b> want some bold </b> here 555";
string html_end = "</font></span></body>\n</html>";
string html_body = html_begin + body + html_end;
msg.Body = html_body;
s.AppendLine("X-ALT-DESC;FMTTYPE=text/html:" + html_body);
msg.Body = html_body;
s.AppendLine("X-ALT_DESC;FMTTYPE=text/html:" + html_body);
s.AppendLine("STATUS:" + status.status); //"CONFIRMED"
s.AppendLine("BEGIN:VALARM");
s.AppendLine("TRIGGER:-PT1440M");
s.AppendLine("ACTION:Accept");
s.AppendLine("DESCRIPTION:Reminder");
s.AppendLine("END:VALARM");
s.AppendLine("END:VEVENT");
s.AppendLine(string.Format("ATTENDEE;CN=\"{0}\";RSVP=TRUE:mailto:{1}", msg.To[0].DisplayName, msg.To[0].Address));
s.AppendLine("END:VCALENDAR");
System.Net.Mime.ContentType type = new System.Net.Mime.ContentType("text/calendar");
type.Parameters.Add("method", method);
type.Parameters.Add("name", "meeting.ics");
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(s.ToString(), type));
SMTP.send(msg);
return EventGuid;
在 outlook 中生成此主体:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 3.2//EN”>
<html>
<head>
<title></title>
</head>
<body>
<!-- Converted from text/rtf format -->
<P DIR=LTR><SPAN LANG=”en-us”>
<Font face=”Times New Roman”I simply <b> want some bold </b> here 555</font></span></body>
</html>
来自测试:
如果我将 Msg.body 排除在外,它只会使用 "DESCRIPTION"。
如果我让它等于 HTML,我会得到上面的结果。
谢谢!
对于未来的人:
问题是使用
.AppendLine
。
只需使用
.Append
我发现HTML字符串必须全部在一行。如果 HTML 分多行,则说明不符合 Vcalendar 编码,说明要么呈现为空白页,要么呈现为所有 HTML 标记都可见的纯文本。
我看到其他人声称必须在 "X-ALT-DESC;FMTTYPE=text/html:" 前面使用 DESCRIPTION 标签。这是完全错误和错误的。如果 "DESCRIPTION" 存在,则优先,"X-ALT-DESC;FMTTYPE=text/html:" 行将被 Outlook 完全忽略,并呈现纯文本描述。所以,"X-ALT-DESC;FMTTYPE=text/html:"一定要自立,要有自己的路线。
工作示例:
...
X-ALT-DESC;FMTTYPE=text/html:<html><body><a href="http://bing.com">Bing</a></body></html>
...
错误:
...
DESCRIPTION;X-ALT-DESC;FMTTYPE=text/html:<html><body><a href="http://bing.com">Bing</a></body></html>
...
又错了:
...
X-ALT-DESC;FMTTYPE=text/html:<html>
<body>
<a href="http://bing.com">Bing</a>
</body>
</html>
...
您可以在多行中使用 X-ALT-DESC,您只需要在其后的每一行的开头添加一个 space。
Lines of text SHOULD NOT be longer than 75 octets, excluding the line break. Long content lines SHOULD be split into a multiple line representations using a line "folding" technique. That is, a long line can be split between any two characters by inserting a CRLF immediately followed by a single linear white-space character (i.e., SPACE or HTAB). Any sequence of CRLF followed immediately by a single linear white-space character is ignored (i.e., removed) when processing the content type.
https://icalendar.org/iCalendar-RFC-5545/3-1-content-lines.html
我加载的 ics 文件不是用适当的 spaces 创建的,它超过 75 个八位字节,如果我手动添加 space 并加载到 Ical.net.Calendar 它工作美好的。但我想通过 C# 代码做同样的事情,比如在加载之前操作日历文件以避免解析错误。
作为参考,这里有来自https://icalendar.org/
的解释
"The original iCalendar standard allowed only plain text as part of an event description. HTML markup, such as font attributes (bold, underline) and layout (div, table) was not allowed in the text description field. First seen in Microsoft Outlook, the X-ALT-DESC parameter provides a method to add HTML to an event description. "X-”字段允许用于 non-standard,实验参数。当在描述中包含 HTML 时,该字段已成为选择的方法。当使用 HTML,必须包含这两个字段,以便不支持 X-ALT-DESC 字段的 iCalendar 读者仍然可以阅读文本版本。"
...看起来 Outlook 2016 已放弃对此的支持。仅生成带有 html 描述的 ics 文件在大多数情况下不是一个选项,因为 Thunderbird/Lightening 过去没有处理导致空主体的日历邀请。
我是 C# 的初学者(老实说是任何网络代码)。我正在尝试发送日历邀请,当您单击公司网站上的按钮时,该邀请就会被发送。这是一个典型的n层系统,使用asp.net/C#和SQL。
我们过去只是简单地生成一个 ics,然后用户必须知道该 ics 才能使用 Outlook 打开,但从那以后我学会了如何手动编写 VCALENDAR 以便它立即在 Outlook 中漂亮整洁地显示出来。
一切都进行得相当顺利,但我现在希望日历邀请的正文能够接受 HTML,特别是附加链接。我已经尝试过 AlternateViews,但似乎 VCALENDAR 中的 "X-ALT-DESC" 属性应该完全符合我的要求。但是,尽我所能尝试 Outlook 忽略它并使用描述。显然我缺少一些东西。
(澄清一下,除了 HTML alt 描述外,一切正常并编译)
private Guid? CreateEmail()
{
Guid eventGuid = Guid.NewGuid();
MailMessage msg = new MailMessage();
msg.IsBodyHtml = true;
msg.From = new MailAddress("fromemail", "From Name");
msg.To.Add(toEmail);
msg.Subject = subject;
StringBuilder s = new StringBuilder();
s.AppendLine("BEGIN:VCALENDAR");
s.AppendLine("VERSION:2.0");
s.AppendLine("PRODID:-//My Product//Outlook MIMEDIR//EN");
s.AppendLine("METHOD:" + method); //In this case, "REQUEST"
s.AppendLine("STATUS:" + status.status); //"CONFIRMED"
s.AppendLine("BEGIN:VEVENT");
s.AppendLine("UID:" + eventGuid.ToString());
s.AppendLine("PRIORITY" + status.priority); //3
s.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:" + ShowAs.ToString()); //"BUSY"
s.AppendLine("SEQUENCE:" + UpdateNumber);//0
s.AppendLine("DTSTAMP:" + DateTime.Now.ToUniversalTime().ToString());
s.AppendLine("DTSTART:" + DateTimetoCalTime(startTime));
s.AppendLine("DTEND:" + DateTimetoCalTime(endTime));
s.AppendLine("SUMMARY:" + subject);
s.AppendLine("LOCATION: " + location);
s.AppendLine("DESCRIPTION: " + "Plain simple description"
string html_begin = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">" +
"\n<html>" +
"\n<head>" +
"\n<title></title>" +
"\n</head>" +
"\n<body>" +
"\n<!-- Converted from text/rtf format -->\n\n<P DIR=LTR><SPAN LANG=\"en-us\">" +
"\n<Font face=\"Times New Roman\"";
body = "I simply <b> want some bold </b> here 555";
string html_end = "</font></span></body>\n</html>";
string html_body = html_begin + body + html_end;
msg.Body = html_body;
s.AppendLine("X-ALT-DESC;FMTTYPE=text/html:" + html_body);
msg.Body = html_body;
s.AppendLine("X-ALT_DESC;FMTTYPE=text/html:" + html_body);
s.AppendLine("STATUS:" + status.status); //"CONFIRMED"
s.AppendLine("BEGIN:VALARM");
s.AppendLine("TRIGGER:-PT1440M");
s.AppendLine("ACTION:Accept");
s.AppendLine("DESCRIPTION:Reminder");
s.AppendLine("END:VALARM");
s.AppendLine("END:VEVENT");
s.AppendLine(string.Format("ATTENDEE;CN=\"{0}\";RSVP=TRUE:mailto:{1}", msg.To[0].DisplayName, msg.To[0].Address));
s.AppendLine("END:VCALENDAR");
System.Net.Mime.ContentType type = new System.Net.Mime.ContentType("text/calendar");
type.Parameters.Add("method", method);
type.Parameters.Add("name", "meeting.ics");
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(s.ToString(), type));
SMTP.send(msg);
return EventGuid;
在 outlook 中生成此主体:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 3.2//EN”>
<html>
<head>
<title></title>
</head>
<body>
<!-- Converted from text/rtf format -->
<P DIR=LTR><SPAN LANG=”en-us”>
<Font face=”Times New Roman”I simply <b> want some bold </b> here 555</font></span></body>
</html>
来自测试: 如果我将 Msg.body 排除在外,它只会使用 "DESCRIPTION"。 如果我让它等于 HTML,我会得到上面的结果。
谢谢!
对于未来的人:
问题是使用
.AppendLine
。
只需使用
.Append
我发现HTML字符串必须全部在一行。如果 HTML 分多行,则说明不符合 Vcalendar 编码,说明要么呈现为空白页,要么呈现为所有 HTML 标记都可见的纯文本。
我看到其他人声称必须在 "X-ALT-DESC;FMTTYPE=text/html:" 前面使用 DESCRIPTION 标签。这是完全错误和错误的。如果 "DESCRIPTION" 存在,则优先,"X-ALT-DESC;FMTTYPE=text/html:" 行将被 Outlook 完全忽略,并呈现纯文本描述。所以,"X-ALT-DESC;FMTTYPE=text/html:"一定要自立,要有自己的路线。
工作示例:
... X-ALT-DESC;FMTTYPE=text/html:<html><body><a href="http://bing.com">Bing</a></body></html> ...
错误:
... DESCRIPTION;X-ALT-DESC;FMTTYPE=text/html:<html><body><a href="http://bing.com">Bing</a></body></html> ...
又错了:
... X-ALT-DESC;FMTTYPE=text/html:<html> <body> <a href="http://bing.com">Bing</a> </body> </html> ...
您可以在多行中使用 X-ALT-DESC,您只需要在其后的每一行的开头添加一个 space。
Lines of text SHOULD NOT be longer than 75 octets, excluding the line break. Long content lines SHOULD be split into a multiple line representations using a line "folding" technique. That is, a long line can be split between any two characters by inserting a CRLF immediately followed by a single linear white-space character (i.e., SPACE or HTAB). Any sequence of CRLF followed immediately by a single linear white-space character is ignored (i.e., removed) when processing the content type.
https://icalendar.org/iCalendar-RFC-5545/3-1-content-lines.html
我加载的 ics 文件不是用适当的 spaces 创建的,它超过 75 个八位字节,如果我手动添加 space 并加载到 Ical.net.Calendar 它工作美好的。但我想通过 C# 代码做同样的事情,比如在加载之前操作日历文件以避免解析错误。
作为参考,这里有来自https://icalendar.org/
的解释"The original iCalendar standard allowed only plain text as part of an event description. HTML markup, such as font attributes (bold, underline) and layout (div, table) was not allowed in the text description field. First seen in Microsoft Outlook, the X-ALT-DESC parameter provides a method to add HTML to an event description. "X-”字段允许用于 non-standard,实验参数。当在描述中包含 HTML 时,该字段已成为选择的方法。当使用 HTML,必须包含这两个字段,以便不支持 X-ALT-DESC 字段的 iCalendar 读者仍然可以阅读文本版本。"
...看起来 Outlook 2016 已放弃对此的支持。仅生成带有 html 描述的 ics 文件在大多数情况下不是一个选项,因为 Thunderbird/Lightening 过去没有处理导致空主体的日历邀请。