|
I think the vCalendar is following the iCalendar specifications which is in the RFC 2445.
http://www.ietf.org/rfc/rfc2445.txt
Sonork 100.41263:Anthony_Yio
|
|
|
|
|
Does anyone know if it is possible to create a recurring event (e.g Last day of every month or every Tuesday).
And if this can be done what would be the best way of representing the frequency of an event in a db?
Thanks
|
|
|
|
|
Here is my incomplete implementation of recurrences:
<br />
public class vRecurrence<br />
{<br />
<br />
public enum Frequencies<br />
{<br />
Daily,<br />
Weekly,<br />
Monthly,<br />
Yearly<br />
}<br />
<br />
public enum DaysOfWeek<br />
{<br />
Sunday,<br />
Monday,<br />
Tuesday,<br />
Wednesday,<br />
Thursday,<br />
Friday,<br />
Saturday<br />
}<br />
<br />
public Frequencies Frequency;<br />
public int Interval = 0;<br />
public DaysOfWeek WeekStart = DaysOfWeek.Sunday;<br />
public DateTime EndDateTime;<br />
public int Occurences = 0;<br />
<br />
private int m_MonthDay;<br />
<br />
public int MonthDay<br />
{<br />
get { return m_MonthDay; }<br />
set<br />
{<br />
if (value >= 1 || value <= 31)<br />
{<br />
m_MonthDay = value;<br />
}<br />
else<br />
{<br />
throw new Exception("MonthDay must be between 1 and 31.");<br />
}<br />
}<br />
}<br />
<br />
public override string ToString()<br />
{<br />
System.Text.StringBuilder result = new System.Text.StringBuilder();<br />
result.Append("RRULE:");<br />
result.AppendFormat("FREQ={0};", Frequency.ToString().ToUpper());<br />
if (Interval > 0)<br />
result.AppendFormat("INTERVAL={0};", Interval);<br />
if (EndDateTime > DateTime.MinValue)<br />
result.AppendFormat("UNTIL={0};", EndDateTime.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));<br />
if (Occurences > 0)<br />
result.AppendFormat("COUNT={0};", Occurences);<br />
result.AppendFormat("WKST={0}", WeekStart.ToString().ToUpper());<br />
return (result.ToString());<br />
}<br />
}<br />
<br />
And add the following to the vEvent class definition:
<br />
public vRecurrence Recurrence;<br />
Again, incomplete I am sure, but it is a start. Remember to check http://www.imc.org/pdi/pdiproddev.html[^] fot the specs.
I you make improvements or see bugs, please consider posting them here for the rest.
http://www.onlinescorekeeper.com/
|
|
|
|
|
I'm very pleased to have found your code here. I'm impressed with the simplicity of it, and the fact that it does much of what I'm looking for.
I've looked around a bit and found references on the web about a proposed standard MIME type for this kind of thing, and I've found a few examples of on-line creators of .vcs files for downloading calendar event items into Outlook.
Looking at the Outlook AppointmentItem object I see lots of properties that would be obvious candidates for the .ics file, but so few actually implemented. Even of those few that are implemented there doesn't seem to be a way to use all the data passed. E.g. your sample has a field URL: that repeats the URL embedded in the Description: field, but once I've imported the event into Outlook I can't see anything (at least in the Outlook UI) that would hold the URL field. The Outlook AppointmentItem object has both MeetingWorkspaceURL and NetShowURL as string properties, but neither appear in the inspector in Outlook.
Outlook also has an EntryID string property, which I assume maps to the ics UID field, but again, nothing to suggest that this would be used to guard against duplicates or check that an entry isn't an update.
I think the only way to get proper control of what goes into which Outlook field is by bypassing the established format and generating your own, and then overriding the Outlook import functionality to properly read all your passed fields into the appropriate Outlook fields. Obviously while there's standard out there, even one with such a bad fit, we would be crazy to try to generate a new one.
C'est la vie!
Brian
----@
|
|
|
|
|
How can you use this test and send as a email to a recipient that has Outlook using the .NET SMTP classes?
|
|
|
|
|
|
I have cut and pasted the code behind code that you provided but it is not working still. All i get is the output put as text in the IE browser.
What am i doing wrong?
thx
|
|
|
|
|
See this post below:
http://www.codeproject.com/vb/net/vcalendar.asp?select=729091&df=100&forumid=14365#xx729091xx
Which says:
Make sure you have this in your sub or function
Response.AddHeader("Content-Disposition", "filename=EventID" + EventID.ToString + ".ics")
|
|
|
|
|
I have this in.
It appears that there is a problem with the ics format. I got it so that i can open the file by adding the following...
Response.ContentType = "application/outlook"
Response.AddHeader("Content-disposition", "attachment; filename=filename.ics")
But as mentioned outlook complains that the format is incorrect. It appears to be something hidden.
Here is the file that is incorrect. Can you see anything wrong with the following?
BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
BEGIN:VEVENT
UID:EventID777
SUMMARY:Event: BBQ
ORGANIZER:Me
LOCATION:Lopez Lake - 1234 Lopez Lake Drive, San Luis Obispo, CA 93401
DTSTART:20040325T184853Z
DTEND:20040325T194853Z
DTSTAMP:20040325T184853Z
DESCRIPTION:View event online:
BEGIN:VALARM
TRIGGER:P1DT0H0M
ACTION:DISPLAY
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR
(ps thx for the fast feeback)
|
|
|
|
|
Caution with this line:
Response.ContentType = "application/outlook"
As it might rule out other PIM applications. But I don't know about that one.
By process of eliminate (and thank goodness it was at the top) outlook doesn't like this:
ORGANIZER:Me
So change it to:
ORGANIZER:Me@msn.com
And outlook opens the event just fine. The beauty is that outlook seems to throw away this ORGANIZER info once it opens the ICS, which makes me wonder why it complains in the first place.
Anyway, hope that helps.
|
|
|
|
|
Thank you very much.
Is there an advantage of ics vs. vcs format?
|
|
|
|
|
Don't know. I never found any specs on vcs, but if you know of some, post it here and I'll give it a look. I looks like maybe vcs doesn't support alarms.
|
|
|
|
|
Here is some more information...
This one works...
Response.AddHeader("Content-disposition", "attachment; filename=" & EventID.ToString & ".ics")
This one does not work
Response.AddHeader("Content-Disposition", "filename=EventID" + EventID.ToString + ".ics")
thoughts?
|
|
|
|
|
Not really, other than:
http://www.hanselman.com/blog/PermaLink.aspx?guid=360
I've never had any problems with it.
|
|
|
|
|
Why are you using the alarm collection? Can an outlook appointment use multiple alarms?
I am just tryting to understand why the collection for the alarms?
thx
dave
|
|
|
|
|
I don't think it can, but it was easy to put in the collection at design time so I didn't want to limit the class if other PIMs were used. Not that I didn't limit the class in other ways
|
|
|
|
|
adding
Response.ContentType = "application/octet-stream";
will make the second work
|
|
|
|
|
Chris,
I understand this works great if creating a new calendar event in ASP and passing data to outlook but what if you were updating an event on an ASP page. Once passed to outlook, would outlook also recognize this as a new event or is there a parameter that can get passed so that outlook would recognize the fact that you are trying to update a previously submitted outlook appointment.
Thanks,
JT
|
|
|
|
|
Although the ics file contains a UniqueID field (UID), outlook does not seem smart enough to use that to determine if an ics file is new or an update. Even when I export an event from outlook and then add it back in, it does not treat it as an update This is using outlook 2003 too!!!
One could only hope that something that simple would be utilized.
|
|
|
|
|
Thanks for the quick response Chris. I figured that was going to be the answer but I was hopefull.
Have a good weekend,
Jack
|
|
|
|
|
Hi,
Do you have (or know of) a C# version for this too?
Thanks,
Neil
|
|
|
|
|
Yep, here ya go:
using System;
using OnlineScorekeeper.Helpers;
namespace OnlineScorekeeper.Helpers
{
public class vCalendar
{
public vEvents Events;
public override string ToString()
{
System.Text.StringBuilder result = new System.Text.StringBuilder();
result.AppendFormat("BEGIN:VCALENDAR{0}", System.Environment.NewLine);
result.AppendFormat("VERSION:2.0{0}", System.Environment.NewLine);
result.AppendFormat("METHOD:PUBLISH{0}", System.Environment.NewLine);
result.Append(Events.ToString());
result.AppendFormat("END:VCALENDAR{0}", System.Environment.NewLine);
return result.ToString();
}
public vCalendar(vEvent value)
{
this.Events.Add(value);
}
public vCalendar()
{
}
public class vRecurrence
{
public enum Frequencies
{
Daily, Weekly, Monthly, Yearly
}
public enum DaysOfWeek
{
Su, Mo, Tu, We, Th, Fr, Sa
}
public Frequencies Frequency;
public int Interval = 0;
public DaysOfWeek WeekStart = DaysOfWeek.Su;
public DateTime EndDateTime;
public int Occurences = 0;
private int m_MonthDay;
public int MonthDay
{
get { return m_MonthDay; }
set
{
if (value >= 1 || value <= 31)
{
m_MonthDay = value;
}
else
{
throw new Exception("MonthDay must be between 1 and 31.");
}
}
}
public override string ToString()
{
System.Text.StringBuilder result = new System.Text.StringBuilder();
result.Append("RRULE:");
result.AppendFormat("FREQ={0};", Frequency.ToString().ToUpper());
if (Interval > 0)
result.AppendFormat("INTERVAL={0};", Interval);
if (EndDateTime > DateTime.MinValue)
result.AppendFormat("UNTIL={0};", EndDateTime.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));
if (Occurences > 0)
result.AppendFormat("COUNT={0};", Occurences);
result.AppendFormat("WKST={0}", WeekStart.ToString().ToUpper());
return (result.ToString());
}
}
public class vAlarm
{
public TimeSpan Trigger;
public string Action;
public string Description;
public vAlarm()
{
Trigger = TimeSpan.FromDays(1);
Action = "DISPLAY";
Description = "Reminder";
}
public vAlarm(TimeSpan setTrigger)
{
Trigger = setTrigger;
Action = "DISPLAY";
Description = "Reminder";
}
public vAlarm(TimeSpan setTrigger, string setAction, string setDescription)
{
Trigger = setTrigger;
Action = setAction;
Description = setDescription;
}
public override string ToString()
{
System.Text.StringBuilder result = new System.Text.StringBuilder();
result.AppendFormat("BEGIN:VALARM{0}", System.Environment.NewLine);
result.AppendFormat("TRIGGER:P{0}DT{1}H{2}M{3}", Trigger.Days, Trigger.Hours, Trigger.Minutes, System.Environment.NewLine);
result.AppendFormat("ACTION:{0}{1}", Action, System.Environment.NewLine);
result.AppendFormat("DESCRIPTION:{0}{1}", Description, System.Environment.NewLine);
result.AppendFormat("END:VALARM{0}", System.Environment.NewLine);
return result.ToString();
}
}
public class vEvent
{
public string UID;
public DateTime DTStart;
public DateTime DTEnd;
public DateTime DTStamp;
public string Summary;
public string Organizer;
public string Location;
public string Description;
public string url;
public vAlarms Alarms = new vAlarms();
public vRecurrence Recurrence;
public bool isPrivate = false;
public override string ToString()
{
System.Text.StringBuilder result = new System.Text.StringBuilder();
result.AppendFormat("BEGIN:VEVENT{0}", System.Environment.NewLine);
result.AppendFormat("UID:{0}{1}", UID, System.Environment.NewLine);
result.AppendFormat("SUMMARY:{0}{1}", Summary, System.Environment.NewLine);
result.AppendFormat("ORGANIZER:{0}{1}", Organizer, System.Environment.NewLine);
result.AppendFormat("LOCATION:{0}{1}", Location, System.Environment.NewLine);
result.AppendFormat("DTSTART:{0}{1}", DTStart.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"), System.Environment.NewLine);
result.AppendFormat("DTEND:{0}{1}", DTEnd.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"), System.Environment.NewLine);
if (Recurrence != null) result.Append(Recurrence.ToString());
result.AppendFormat("DTSTAMP:{0}{1}", DateTime.Now.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"), System.Environment.NewLine);
result.AppendFormat("DESCRIPTION:{0}{1}", Description, System.Environment.NewLine);
if (!Strings.IsBlank(url)) result.AppendFormat("URL:{0}{1}", url, System.Environment.NewLine);
result.Append(Alarms.ToString());
if (isPrivate)
result.AppendFormat("CLASS:{0}{1}", "PRIVATE", System.Environment.NewLine);
else
result.AppendFormat("CLASS:{0}{1}", "PUBLIC", System.Environment.NewLine);
result.AppendFormat("END:VEVENT{0}", System.Environment.NewLine);
return result.ToString();
}
}
public class vAlarms : System.Collections.CollectionBase
{
public vAlarm Add(vAlarm value)
{
this.InnerList.Add(value);
return (value);
}
public vAlarm Item(int index)
{
return (vAlarm) this.InnerList[index];
}
public void Remove(int index)
{
vAlarm cust = (vAlarm) this.InnerList[index];
if (cust != null)
this.InnerList.Remove(cust);
}
public override string ToString()
{
System.Text.StringBuilder result = new System.Text.StringBuilder();
foreach(vAlarm item in this.InnerList)
{
result.Append(item.ToString());
}
return (result.ToString());
}
}
public class vEvents : System.Collections.CollectionBase
{
public vEvent Add(vEvent value)
{
this.InnerList.Add(value);
return value;
}
public vEvent Item(int index)
{
return (vEvent) this.InnerList[index];
}
public void Remove(int index)
{
vEvent cust = (vEvent) this.InnerList[index];
if (cust != null)
this.InnerList.Remove(cust);
}
public override string ToString()
{
System.Text.StringBuilder result = new System.Text.StringBuilder();
foreach(vEvent item in this.InnerList)
{
result.Append(item.ToString());
}
return (result.ToString());
}
}
}
}
|
|
|
|
|
Hello there.
Thanks for your vCalendar class which is great . However, I have a question. I want to attach your vCalendar to e-mails (I assume that is how to use it from smtp applications) and it seems that attachments must be physical files on the hard-drive (rather than just in-memory objects). So, the question is: How do I serialise your vCalendar to disk? Alternatively: Is there another way to attach the vCalendar object to an e-mail?
Thanks and Best Regards,
Cliff Woodger
|
|
|
|
|
Well, the VCalendar.ToString() function just spits all of info out to a string, properly formatted. I have not used it to make attachments to emails, just streamed them to the browser after changing the content type. I suspect the only way to use a vcalendar object as an attachment using the standard Mail namespace functions is to first save the vcalendar.ToString output to a file and then attach, then delete the file if necessary. Or look at the tons of other .NET mail components available to see if any support attaching in memory objects and giving them a filename and content time.
Sorry I couldn't be more help.
|
|
|
|
|
The concept is great, I have been looking for this for quite some time. Do you have an example of it actually being used?
|
|
|
|
|