如何使用C#创建.ics文件?

19

在此输入图像描述我使用了下面的代码来创建.ics文件,但它没有工作,有人可以帮我吗,看看哪里出错了。

System.Text.StringBuilder sbICSFile = new System.Text.StringBuilder();
sbICSFile.AppendLine("BEGIN:VCALENDAR");
sbICSFile.AppendLine("VERSION:2.0");
sbICSFile.AppendLine("PRODID:-//ICSTestCS/");
sbICSFile.AppendLine("CALSCALE:GREGORIAN");
sbICSFile.AppendLine("BEGIN:VTIMEZONE");

----------
----------
Response.ContentType = "text/calendar";
Response.ContentEncoding = Encoding.UTF8;
Response.Charset = "utf-8";
Response.AddHeader("Content-Disposition", "attachment;filename=Test.ics");
Response.Write(sbICSFile);
Response.End();

1
Response.Write(sbICSFile); 更改为 Response.Write(sbICSFile.ToString()); - 您正在发送 StringBuilder 实例而不是构建的字符串。 - Filburt
创建文件后,我将其添加到日历中,但显示无法打开事件。可能是日历文件已损坏。 - amit
我也尝试了Response.Write(sbICSFile.ToString());,但仍然不起作用。 - amit
@amit - 现在创建已经可以了。问题是添加(假设实际内容正确; 你有双重检查吗?不熟悉ics格式)。你如何添加? - Corak
那个错误是什么? - Corak
显示剩余9条评论
3个回答

29

这是我通常创建.ics文件的方法。

//some variables for demo purposes
DateTime DateStart = DateTime.Now;
DateTime DateEnd = DateStart.AddMinutes(105);
string Summary = "Small summary text";
string Location = "Event location";
string Description = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.";
string FileName = "CalendarItem";

//create a new stringbuilder instance
StringBuilder sb = new StringBuilder();

//start 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 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 time zone specified
sb.AppendLine("DTSTART;TZID=Europe/Amsterdam:" + DateStart.ToString("yyyyMMddTHHmm00"));
sb.AppendLine("DTEND;TZID=Europe/Amsterdam:" + DateEnd.ToString("yyyyMMddTHHmm00"));
//or without
sb.AppendLine("DTSTART:" + DateStart.ToString("yyyyMMddTHHmm00"));
sb.AppendLine("DTEND:" + DateEnd.ToString("yyyyMMddTHHmm00"));

sb.AppendLine("SUMMARY:" + Summary + "");
sb.AppendLine("LOCATION:" + Location + "");
sb.AppendLine("DESCRIPTION:" + Description + "");
sb.AppendLine("PRIORITY:3");
sb.AppendLine("END:VEVENT");

//end calendar item
sb.AppendLine("END:VCALENDAR");

//create a string from the stringbuilder
string CalendarItem = sb.ToString();

//send the calendar item to the browser
Response.ClearHeaders();
Response.Clear();
Response.Buffer = true;
Response.ContentType = "text/calendar";
Response.AddHeader("content-length", CalendarItem.Length.ToString());
Response.AddHeader("content-disposition", "attachment; filename=\"" + FileName + ".ics\"");
Response.Write(CalendarItem);
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();

谢谢,现在我可以将其添加到日历中了,但是有一个问题,在添加到日历时它会取昨天的日期,比如我传递的是今天的日期,它会取昨天的日期,为什么会取昨天的日期呢?你能帮我吗? - amit
2
检查时区是否正确,尝试使用和不使用。 - VDWWD
string eventDate = Convert.ToDateTime(lblEventDate.Text).ToString("yyyyMMddT000000Z"); 我这样转换可以正常工作,但我只想要日期,时间应该是000000,我该如何转换? - amit
1
你可以这样做:DateStart.ToString("yyyyMMddT000000") 或者 DateStart.ToString("yyyyMMdd") + "T000000" - VDWWD
string eventDate = Convert.ToDateTime(lblEventDate.Text).Date.ToString("yyyyMMddTHHmm00Z");注意 .Date - VISHMAY
1
在字符串构建器中使用字符串连接让我感到非常头疼。此外,(Summary +“”)?好在我们添加了这个空字符串,没有任何理由,只是为了增加内存使用。 - JSON

7

除了被接受的答案之外,您还必须添加 UID 和 DTSTAMP 才能适用于谷歌日历。 这是我添加的内容:

sb.AppendLine("UID:" + (Guid.NewGuid().ToString() + DateTime.Now.ToString("yyyyMMddTHHmm00")));
sb.AppendLine("DTSTAMP:" + DateTime.Now.ToString("yyyyMMddTHHmm00"));

您也可以在此处测试您的内容。


你把这个加在哪里? - JSON
1
你可以在 END:VEVENT 行之前立即添加此行。 - Mike Kormendy

4

我曾经尝试构建支持时区的ics文件,但是一直失败。最终我选择了ical.Net来生成文件。他们的wiki上有一个基本的示例,可以帮助你生成文件。下面是需要时区支持时的示例:

var startDate = DateTime.Now;
var endDate = startDate.AddHours(1);
var calendar = new Calendar
               {
                  Method = "PUBLISH",
               };
calendar.AddTimeZone("America/Chicago");
var calendarEvent = new CalendarEvent
        {
            Description = "Your description here",
            End = new CalDateTime(endDate, "America/Chicago"),
            Location = "Your location here",
            Start = new CalDateTime(startDate, "America/Chicago"),
            Summary = "Your summary here"
        };
calendar.Events.Add(calendarEvent);

然后,要将ics文件作为字符串获取:
var serializer = new CalendarSerializer();
var iscFile = serializer.SerializeToString(calendar);

最后,我建议您使用此工具验证您的结果。希望这能为某些人节省时间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接