76

我正在寻找一种在 c# (asp.net) 中生成 iCalendar 文件 (*.ics) 的好方法。我找到了一些资源,但缺少的一件事是它们对引用可打印字段的支持 - 具有回车和换行符的字段。

例如,如果描述字段未正确编码,则只会显示第一行,并可能破坏 *.ics 文件中的其余信息。

我正在寻找可以生成 *.ics 文件的现有类和/或可以生成带引号的可打印字段的类。

4

9 回答 9

73

我使用DDay.Ical,它的好东西。能够打开一个 ical 文件并在一个不错的对象模型中获取其数据。它说的是测试版,但它对我们很有用。

编辑 2016 年 11 月

该库已被弃用,但被另一个开发人员拾取并重新发布为 iCal.NET。

发布说明:rianjs.net/2016/07/dday-ical-is-now-ical-net

GitHub上的来源:github.com/rianjs/ical.net

于 2008-08-14T04:09:48.813 回答
12

我发现这样做的最简单方法是使用microformats标记您的 HTML 。

如果您要生成 iCalendar 文件,则可以使用hCalendar 微格式,然后包含一个链接,例如“添加到日历”,该链接指向:

http://feeds.technorati.com/events/[您页面的完整 URL,包括 http:// ]

然后 Technorati 页面解析您的页面,提取 hCalendar 信息并将 iCalendar 文件发送到客户端。

于 2008-08-20T08:02:15.577 回答
3

我写了一个 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")。只要您将缓存设置得相当长,操作就不会太昂贵。

于 2011-01-21T21:15:57.873 回答
2

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 之间似乎存在混淆。

于 2009-05-15T19:11:56.157 回答
2

我缺少自定义时区的示例。所以这里有一个片段,展示了如何在 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();
于 2017-10-19T19:23:28.080 回答
1

查看http://www.codeproject.com/KB/vb/vcalendar.aspx

它不会像您询问的那样处理带引号的可打印字段,但其余代码都在那里并且可以修改。

于 2008-08-19T18:51:07.673 回答
1

根据 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.
于 2009-05-15T18:47:52.300 回答
0

iCal 可能很复杂,所以我建议使用库。DDay 是一个很好的免费解决方案。最后我检查了它没有完全支持重复事件,但除此之外它看起来真的很好。一定要与几个客户一起测试日历。

于 2008-08-14T06:10:00.863 回答
0

我知道为时已晚,但它可能对其他人有所帮助。就我而言,我编写了以下带有 .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

它对我有用。

于 2017-05-09T18:19:20.967 回答