【问题标题】:Creating iCal Files in c#在 c# 中创建 iCal 文件
【发布时间】:2010-09-05 20:32:44
【问题描述】:

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

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

我正在寻找可以生成 *.ics 文件的现有类和/或可以生成 quoted-printable 字段的类。

【问题讨论】:

  • 尽管这个问题发生在很久以前,但我想我要指出引用可打印字段不是 iCalendar 标准(vCalendar 2.0)的一部分。它们是 vCalendar 标准 (vCalendar 1.0) 的一部分,现在很少(如果有的话)使用。 iCalendar 有自己的转义数据的方法,它比引用打印的更清晰和更容易解释。

标签: c# asp.net icalendar


【解决方案1】:

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

2016 年 11 月编辑

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

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

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

【讨论】:

    【解决方案2】:

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

    如果您希望生成 iCalendar 文件,那么您可以使用 hCalendar microformat 然后包含一个链接,例如“添加到日历”,该链接指向:

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

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

    【讨论】:

    • NerdDinner.com 使用此方法,似乎效果很好。也就是说,我必须为 DDay.iCal +1 (虽然我am 有偏见):)
    • 我不喜欢这种方法的是 technorati 可能会更改其规格甚至关闭服务。不过这是个好主意。
    【解决方案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")。只要您将缓存设置得相当长,它的操作成本就不会太高。

    【讨论】:

    • 受您的代码启发,我重写了它(尽管使用 C#),其中解析是按块而不是按字符。可以在相关问题上查看:stackoverflow.com/a/27164955/914512
    【解决方案4】:

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

    【讨论】:

    • 感谢您强调 UTF-8 是默认编码。
    【解决方案5】:

    我缺少自定义时区的示例。所以这里有一个 sn-p,它展示了如何在 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();
    

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

        根据 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.
        

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

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

            它对我有用。

            【讨论】:

              猜你喜欢
              • 2013-01-27
              • 1970-01-01
              • 1970-01-01
              • 2020-09-20
              • 1970-01-01
              • 1970-01-01
              • 2015-03-05
              • 2010-12-14
              • 2023-03-23
              相关资源
              最近更新 更多