我正在寻找一种在c#(asp.net)中生成iCalendar文件(* .ics)的好方法。我找到了一些资源,但缺少的一点是他们支持 quoted-printable 字段 - 具有回车符和换行符的字段。
例如,如果 description 字段编码不正确,则只会显示第一行,并可能损坏* .ics文件中的其余信息。
我正在寻找可以生成* .ics文件的现有类和/或可以生成 quoted-printable 字段的类。
答案 0 :(得分:72)
我使用DDay.Ical,它的好东西。 能够打开一个ical文件并在一个漂亮的对象模型中获取它的数据。它说beta,但它对我们很有用。
这个库已被弃用,但被另一个开发者选中并重新发布为iCal.NET。
有关发布的说明:rianjs.net/2016/07/dday-ical-is-now-ical-net
GitHub上的来源:github.com/rianjs/ical.net
答案 1 :(得分:12)
我发现这样做的最简单方法是使用microformats标记HTML。
如果您要生成iCalendar文件,则可以使用hCalendar microformat,然后添加指向“添加到日历”的链接:
http://feeds.technorati.com/events/[您网页的完整网址,包括http://]
然后,Technorati页面会解析您的页面,提取hCalendar信息并将iCalendar文件发送给客户端。
答案 2 :(得分: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 Feed的摘要和说明。只需输入已经预先添加的字段的行(例如,LongText =“SUMMARY:Event Title”)。只要你将缓存设置得相当长,就不会太昂贵了。
答案 3 :(得分: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之间似乎存在混淆。
答案 4 :(得分:1)
查看http://www.codeproject.com/KB/vb/vcalendar.aspx
它不像你问的那样处理引用的可打印字段,但其余的代码都在那里,可以修改。
答案 5 :(得分:1)
根据RFC-2445,注释和描述字段是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.
答案 6 :(得分:0)
iCal可能很复杂,所以我建议使用库。 DDay是一个很好的免费解决方案。最后我检查它没有完全支持重复发生的事件,但除此之外,它看起来非常好。绝对要测试几个客户的日历。
答案 7 :(得分: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
它对我有用。
答案 8 :(得分:0)
我错过了自定义时区的示例。所以这里有一个片段,展示如何在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();