我正在寻找一种在 c# (asp.net) 中生成 iCalendar 文件 (*.ics) 的好方法。我找到了一些资源,但缺少的一件事是它们对引用可打印字段的支持 - 具有回车和换行符的字段。
例如,如果描述字段未正确编码,则只会显示第一行,并可能破坏 *.ics 文件中的其余信息。
我正在寻找可以生成 *.ics 文件的现有类和/或可以生成带引号的可打印字段的类。
我使用DDay.Ical,它的好东西。能够打开一个 ical 文件并在一个不错的对象模型中获取其数据。它说的是测试版,但它对我们很有用。
该库已被弃用,但被另一个开发人员拾取并重新发布为 iCal.NET。
发布说明:rianjs.net/2016/07/dday-ical-is-now-ical-net
GitHub上的来源:github.com/rianjs/ical.net
我发现这样做的最简单方法是使用microformats标记您的 HTML 。
如果您要生成 iCalendar 文件,则可以使用hCalendar 微格式,然后包含一个链接,例如“添加到日历”,该链接指向:
http://feeds.technorati.com/events/[您页面的完整 URL,包括 http:// ]
然后 Technorati 页面解析您的页面,提取 hCalendar 信息并将 iCalendar 文件发送到客户端。
我写了一个 shim 函数来处理这个问题。它基本上是合规的——唯一的问题是第一行是 74 个字符而不是 75 个(74 是处理后续行的空格)......
Private Function RFC2445TextField(ByVal LongText As String) As String
LongText = LongText.Replace("\", "\\")
LongText = LongText.Replace(";", "\;")
LongText = LongText.Replace(",", "\,")
Dim sBuilder As New StringBuilder
Dim charArray() As Char = LongText.ToCharArray
For i = 1 To charArray.Length
sBuilder.Append(charArray(i - 1))
If i Mod 74 = 0 Then sBuilder.Append(vbCrLf & " ")
Next
Return sBuilder.ToString
End Function
我将其用于我们的 ICS 提要的摘要和描述。只需在前面添加字段(例如 LongText = "SUMMARY:Event Title")。只要您将缓存设置得相当长,操作就不会太昂贵。
iCal (ical 2.0) 和quoted-printable 不能一起使用。
Quoted-printable 在vCal (vCal 1.0)中被大量使用来表示不可打印的字符,例如换行符 (=0D=0A)。默认的 vCal 编码是 7 位的,所以有时需要使用quoted-printable 来表示非 ASCII 字符(可以覆盖默认编码,但不需要其他符合 vCal 的通信方理解它。)
在iCal中,特殊字符使用转义符表示,例如 '\n'。默认编码是 UTF-8,所有 iCal 兼容方都必须支持它,这使得在 iCal 2.0(和 vCard 3.0,就此而言)完全不需要引用打印。
您可能需要支持您的客户/利益相关者来阐明要求。vCal 和 iCal 之间似乎存在混淆。
我缺少自定义时区的示例。所以这里有一个片段,展示了如何在 ics 中设置时区(并将其发送到 asp.net 中的浏览器)。
//set a couple of variables for demo purposes
DateTime IcsDateStart = DateTime.Now.AddDays(2);
DateTime IcsDateEnd = IcsDateStart.AddMinutes(90);
string IcsSummary = "ASP.Net demo snippet";
string IcsLocation = "Amsterdam (Netherlands)";
string IcsDescription = @"This snippes show you how to create a calendar item file (.ics) in ASP.NET.\nMay it be useful for you.";
string IcsFileName = "MyCalendarFile";
//create a new stringbuilder instance
StringBuilder sb = new StringBuilder();
//begin the calendar item
sb.AppendLine("BEGIN:VCALENDAR");
sb.AppendLine("VERSION:2.0");
sb.AppendLine("PRODID:stackoverflow.com");
sb.AppendLine("CALSCALE:GREGORIAN");
sb.AppendLine("METHOD:PUBLISH");
//create a custom time zone if needed, TZID to be used in the event itself
sb.AppendLine("BEGIN:VTIMEZONE");
sb.AppendLine("TZID:Europe/Amsterdam");
sb.AppendLine("BEGIN:STANDARD");
sb.AppendLine("TZOFFSETTO:+0100");
sb.AppendLine("TZOFFSETFROM:+0100");
sb.AppendLine("END:STANDARD");
sb.AppendLine("END:VTIMEZONE");
//add the event
sb.AppendLine("BEGIN:VEVENT");
//with a time zone specified
sb.AppendLine("DTSTART;TZID=Europe/Amsterdam:" + IcsDateStart.ToString("yyyyMMddTHHmm00"));
sb.AppendLine("DTEND;TZID=Europe/Amsterdam:" + IcsDateEnd.ToString("yyyyMMddTHHmm00"));
//or without a time zone
//sb.AppendLine("DTSTART:" + IcsDateStart.ToString("yyyyMMddTHHmm00"));
//sb.AppendLine("DTEND:" + IcsDateEnd.ToString("yyyyMMddTHHmm00"));
//contents of the calendar item
sb.AppendLine("SUMMARY:" + IcsSummary + "");
sb.AppendLine("LOCATION:" + IcsLocation + "");
sb.AppendLine("DESCRIPTION:" + IcsDescription + "");
sb.AppendLine("PRIORITY:3");
sb.AppendLine("END:VEVENT");
//close calendar item
sb.AppendLine("END:VCALENDAR");
//create a string from the stringbuilder
string CalendarItemAsString = sb.ToString();
//send the ics file to the browser
Response.ClearHeaders();
Response.Clear();
Response.Buffer = true;
Response.ContentType = "text/calendar";
Response.AddHeader("content-length", CalendarItemAsString.Length.ToString());
Response.AddHeader("content-disposition", "attachment; filename=\"" + IcsFileName + ".ics\"");
Response.Write(CalendarItemAsString);
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
查看http://www.codeproject.com/KB/vb/vcalendar.aspx
它不会像您询问的那样处理带引号的可打印字段,但其余代码都在那里并且可以修改。
根据 RFC-2445,comment 和 description 字段是 TEXT。测试字段的规则是: [1] TEXT 字段中的单行不超过 75 个八位字节。[2] 包装是通过插入 CRLF 后跟空格来实现的。[3] 有几个字符必须编码,包括\(反斜杠);(分号)、(逗号)和换行符。使用 \(反斜杠)作为分隔符给出 \ \; \, \n
示例:以下是属性值中带有格式化换行符的属性示例:
DESCRIPTION:Meeting to provide technical review for "Phoenix"
design.\n Happy Face Conference Room. Phoenix design team
MUST attend this meeting.\n RSVP to team leader.
iCal 可能很复杂,所以我建议使用库。DDay 是一个很好的免费解决方案。最后我检查了它没有完全支持重复事件,但除此之外它看起来真的很好。一定要与几个客户一起测试日历。
我知道为时已晚,但它可能对其他人有所帮助。就我而言,我编写了以下带有 .ics 扩展名的文本文件
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Calendly//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
DTSTAMP:20170509T164109Z
UID:your id-11273661
DTSTART:20170509T190000Z
DTEND:20170509T191500Z
CLASS:PRIVATE
DESCRIPTION:Event Name: 15 Minute Meeting\nDate & Time: 03:00pm - 03:15pm (
Eastern Time - US & Canada) on Tuesday\, May 9\, 2017\n\nBest Phone Number
To Reach You :: xxxxxxxxx\n\nany "link": https://wwww.yahoo.com\n\n
SUMMARY:15 Minute Meeting
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
它对我有用。