2008-08-14 36 views
73

Tôi đang tìm một phương pháp tốt để tạo tệp iCalendar (* .ics) trong C# (asp.net). Tôi đã tìm thấy một vài tài nguyên, nhưng một điều thiếu sót là sự hỗ trợ của họ đối với các trường được trích dẫn có thể in được - các trường có trả về dòng và nguồn cấp dữ liệu dòng.Tạo tập tin iCal trong C#

Ví dụ: nếu trường mô tả không được mã hóa đúng cách, chỉ dòng đầu tiên sẽ hiển thị và có thể làm hỏng phần còn lại của thông tin trong tệp * .ics.

Tôi đang tìm các lớp hiện có có thể tạo tệp * .ics và/hoặc lớp học có thể tạo ra các trường được trích dẫn có thể in được được trích dẫn.

+8

Mặc dù câu hỏi này xảy ra một thời gian dài trước đây, tôi nghĩ tôi chỉ ra rằng các trường có thể in được là * không * một phần của tiêu chuẩn iCalendar (vCalendar 2.0). Chúng là một phần của tiêu chuẩn vCalendar (vCalendar 1.0) hiếm khi được sử dụng ngày nay. iCalendar có phương pháp thoát dữ liệu riêng của mình, sạch hơn và dễ hiểu hơn nhiều so với bản in được trích dẫn. – Doug

Trả lời

70

Tôi sử dụng DDay.Ical, nội dung hay của nó. Có khả năng mở một tệp ical và lấy dữ liệu của nó trong một mô hình đối tượng đẹp. Nó nói beta, nhưng nó hoạt động tuyệt vời cho chúng ta.

Sửa Tháng Mười Một 2016

Thư viện này đã bị phản đối, nhưng đã nhặt và tái phát hành dưới dạng iCal.NET bởi dev khác.

Ghi chú về việc phát hành: rianjs.net/2016/07/dday-ical-is-now-ical-net

Nguồn trên GitHub: github.com/rianjs/ical.net

+2

Liên kết ở trên bị hỏng. Đây là liên kết SourceForge: http://sourceforge.net/projects/dday-ical/ –

+0

cảm ơn, cập nhật – DevelopingChris

+0

Đáng tiếc rằng DDay.Ical không được ký kết mạnh mẽ vì vậy nó không thể được tham chiếu bởi các hội đồng được ký mạnh mẽ: ( –

0

iCal có thể phức tạp, vì vậy tôi khuyên bạn nên sử dụng một thư viện. DDay là một giải pháp miễn phí tốt. Cuối cùng tôi đã kiểm tra nó không có hỗ trợ đầy đủ cho các sự kiện lặp lại, nhưng khác hơn là nó trông rất đẹp. Chắc chắn kiểm tra lịch với nhiều khách hàng.

12

Cách dễ nhất tôi đã tìm thấy để thực hiện việc này là đánh dấu HTML của bạn bằng cách sử dụng microformats.

Nếu bạn đang tìm kiếm để tạo ra các file iCalendar sau đó bạn có thể sử dụng hCalendar microformat sau đó bao gồm một liên kết như 'Thêm vào Lịch' trỏ đến:

http://feeds.technorati.com/events/[ URL đầy đủ của trang web của bạn bao gồm cả http: // ]

Trang Technorati sau đó phân tích trang của bạn, trích xuất thông tin hCalendar và gửi tệp iCalendar tới ứng dụng khách.

+3

Phương pháp này được sử dụng bởi NerdDinner.com và có vẻ hoạt động khá độc đáo, điều đó nói rằng, tôi phải cung cấp +1 cho DDay.iCal (mặc dù tôi * am * thành kiến) :) – Doug

+0

Wha Tôi không thích phương pháp này là technorati có thể thay đổi thông số kỹ thuật của nó hoặc thậm chí tắt dịch vụ. Đó là một ý tưởng tốt mặc dù. –

1

Theo RFC-2445, trường nhận xét và mô tả là TEXT. Các quy tắc cho một trường thử nghiệm là: [1] Một dòng trong trường TEXT không được vượt quá 75 octet. [2] Gói được thực hiện bằng cách chèn một CRLF theo sau là khoảng trắng. [3] Có một số ký tự phải được mã hóa bao gồm \ (dấu gạch chéo ngược); (dấu chấm phẩy), (dấu phẩy) và dòng mới. Sử dụng dấu \ (dấu gạch chéo ngược) làm dấu phân tách cho \ \; \, \ N

Ví dụ: Sau đây là một ví dụ về tài sản với định dạng ngắt dòng trong giá trị tài sả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. 
2

iCal (ical 2.0) và được trích dẫn-in không đi cùng nhau.

Trích dẫn có thể in được sử dụng rất nhiều trong vCal (vCal 1.0) để thể hiện các ký tự không in được, ví dụ: ngắt dòng (= 0D = 0A). Mã hóa vCal mặc định là 7-bit, vì vậy đôi khi bạn cần sử dụng có thể in được để thể hiện các ký tự không phải ASCII (bạn có thể ghi đè mã hóa mặc định, nhưng bên giao tiếp tương thích vCal khác không bắt buộc phải hiểu nó.)

Trong iCal, các ký tự đặc biệt được thể hiện bằng cách thoát, ví dụ: '\ n'. Mã hóa mặc định là UTF-8, tất cả các bên tuân thủ iCal phải hỗ trợ nó và điều đó làm cho bản in có thể in hoàn toàn không cần thiết trong iCal 2.0 (và vCard 3.0, cho vấn đề đó).

Bạn có thể cần phải quay lại khách hàng/bên liên quan của mình để làm rõ các yêu cầu. Dường như có sự nhầm lẫn giữa vCal và iCal.

+0

Cảm ơn bạn đã đánh dấu UTF-8 là mã hóa mặc định. –

3

Tôi đã viết một hàm shim để xử lý việc này. Đó chủ yếu là phù hợp - các gác máy duy nhất là dòng đầu tiên là 74 ký tự thay vì 75 (74 là để xử lý các không gian trên dòng tiếp theo) ...

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 

tôi sử dụng này cho các bản tóm tắt và mô tả trên nguồn cấp dữ liệu ICS của chúng tôi. Chỉ cần cung cấp dòng với trường đã được thêm trước (ví dụ: LongText = "SUMMARY: Event Title"). Miễn là bạn đặt bộ nhớ đệm quá lâu, nó không phải là quá đắt của một hoạt động.

+0

Lấy cảm hứng từ mã của bạn, tôi viết lại nó (sử dụng C# mặc dù) trong đó phân tích cú pháp là theo khối và không phải là ký tự khôn ngoan. Có thể kiểm tra nó tại một câu hỏi liên quan: http://stackoverflow.com/a/27164955/914512 – reexmonkey

0

tôi biết đã quá muộn nhưng có thể giúp người khác. trong trường hợp của tôi, tôi đã viết tập tin văn bản sau đây với phần mở rộng .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 

nó làm việc cho tôi.

0

Tôi thiếu một ví dụ có múi giờ tùy chỉnh. Vì vậy, ở đây một đoạn mã cho thấy cách bạn có thể thiết lập một múi giờ trong ics (và gửi nó đến trình duyệt trong 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();