Sending Meeting Requests to Outlook via ASP.NET Mail Message

Numerous programs on my company deal with event registration. Naturally, that involves sending our employees meeting requests. Here’s the best way I’ve found so far for doing that. The long function at the end is from a web-service already in use for a few months.

Meeting Request

Meeting Request

To make these ICS files dynamically, I use the .Net library DDay.iCal. It’s aewsome.
It took some trial and error, but at the end I was able to create events that work well for all versions of Outlook.
Unlike the solutions I’ve found on the web, this one doesn’t use the office interop thing, so I don’t need outlook installed on the server. I’m using a regular SMTP mail message and add the ICS as attachment.

Anyway, assuming you know how to send mails and how to generate the right ICS for your event (we’ll get to that later), this is the way to send it to Outlook:
First the variables:

//init the message with your defaults (from, to, subject, etc)
MailMessage message = initMailMessage();
string iCal = initICal(parameters ...);

And the code that adds the attachment:

//Add the attachment, specify it is a calendar file.
System.Net.Mail.Attachment attachment =
System.Net.Mail.Attachment.CreateAttachmentFromString(
iCal, new ContentType("text/calendar"));
attachment.TransferEncoding = TransferEncoding.Base64;
attachment.Name = "EventDetails.ics"; //not visible in outlook

message.Attachments.Add(attachment);

sendMailMessage(message);

Ok. That’s probably disappointing, since you can’t just copy-paste this code and make it work. I’m including more code you may want to use, but first some rules for the ICS files you’re about to create:

Rules of Thumb

  • Make sure to specify the Method property – should be Publish or Request. Outlook won’t accept the file without it.
  • Add an Organizer – or Outlook 2007 won’t let people save the event.
  • Add the meeting’s subject and description to the ICS file, but also as the mail’s subject and body. Outlook may display either one.

Now for that extra code.
This one is pretty simple – sends an SMTP message:

private static void sendMailMessage(MailMessage mailMessage)
{
string mailHost = "Ask.Someone.com";
SmtpClient smtpClient = new SmtpClient(mailHost, 25);
smtpClient.DeliveryMethod =
   SmtpDeliveryMethod.PickupDirectoryFromIis;
smtpClient.Send(mailMessage);
}

This fine function creates the ICS:

[WebMethod(Description =
   "Send an appointment with much details.")]
public void SendAppointment(string from, string to,
   string title, string body, DateTime startDate,
   double duration, string location, string organizer,
   bool updatePreviousEvent, string eventId,
   bool allDayEvent,
   int recurrenceDaysInterval, int recurrenceCount)
{
  iCalendar iCal = new iCalendar();

  // outlook 2003 needs this property,
  //  or we'll get an error (a Lunar error!)
  iCal.Method = "PUBLISH";

  // Create the event
  Event evt = iCal.Create();

  evt.Summary = title;

  evt.Start = new iCalDateTime(startDate.Year,
    startDate.Month, startDate.Day, startDate.Hour,
    startDate.Minute, startDate.Second);
  evt.Duration = TimeSpan.FromHours(duration);
  evt.Description = body;
  evt.Location = location;

  if (recurrenceDaysInterval > 0)
  {
    RecurrencePattern rp = new RecurrencePattern();
    rp.Frequency = FrequencyType.Daily;
    rp.Interval = recurrenceDaysInterval; // interval of days

    rp.Count = recurrenceCount;
    evt.AddRecurrencePattern(rp);
  }
  evt.IsAllDay = allDayEvent;

  //organizer is mandatory for outlook 2007 - think about
  // trowing an exception here.
  if (!String.IsNullOrEmpty(organizer))
    evt.Organizer = organizer;


  if (!String.IsNullOrEmpty(eventId))
    evt.UID = eventId;

  //"REQUEST" will update an existing event with the same
  // UID (Unique ID) and a newer time stamp.
  if (updatePreviousEvent)
    iCal.Method = "REQUEST";

  // Save into calendar file.
  iCalendarSerializer serializer =
    new iCalendarSerializer(iCal);
  //serializer.Serialize(@"iCalendar.ics");

  string icalData = serializer.SerializeToString();

  //send the iCal data. Also sends the subject and body
  //on the mail.
  SendAppointmentFromICalWithMailTitle(from, to,
    icalData, title, body);
}

See Also:

Advertisements

47 thoughts on “Sending Meeting Requests to Outlook via ASP.NET Mail Message

    • The meeting request is sent as an email message, so you don’t need iCal for that.
      What exactly do you mean by ‘Outlook message’?

  1. A regular message. I want to build a system that gets the message details and sends it on a set time (like 20:00) 😉

    • If all you need is a regular mail, I have a small function here that can do that, sendMailMessage. You can find many examples for that on the net.
      If you’re in the army though, they’ve probably closed all mail servers and ports (I tried that a while back, Mor looked for them too). Mamram have a web service that sends mails, maybe you’ll have better luck getting a user than I did. (I found a name and password at a code example on z-net, and made a web service that encapsulates that on Eli’s server).

  2. Hi Kobi,

    I use this method but only can get a message with meeting request attachment. How can I get meeting request directly in outlook 2k3?
    Thanks.

    • Hello Chris,
      The key here is this line:
      System.Net.Mail.Attachment.CreateAttachmentFromString(iCal, new ContentType(“text/calendar”));
      This should turn the message into a meeting request. Also, make sure to include Method and Organizer.
      A good tip here is to send there requests to gmail. You can than view the source and see exactly what’s gong on, by decoding the attachment from base 64.

  3. Hi Kobi,
    Your keys are already included in my codes, but still mails with attachment either received in outlook 2k3 or in gmail.
    Kindly check my codes? Few changes from your codes.Thanks a lot!!

    //Using DDay.iCal 0.7.0
    //parameters
    string title = “Test”;
    string body = “Test body”;
    DateTime startDate = DateTime.Now;
    double duration = 1;
    string location = “B4F1 Meeting Room”;
    string organizer = “Chris G”;
    bool updatePreviousEvent = false;
    string eventId = “000832”;
    bool allDayEvent = false;
    int recurrenceDaysInterval = 0;
    int recurrenceCount = 0;

    iCalendar iCal = new iCalendar();

    // outlook 2003 needs this property,
    // or we’ll get an error (a Lunar error!)
    iCal.Method = “PUBLISH”;

    // Create the event
    Event evt = iCal.Create();

    evt.Summary = title;
    evt.Start = new iCalDateTime(startDate.Year,startDate.Month, startDate.Day, startDate.Hour,startDate.Minute, startDate.Second);
    evt.Duration = TimeSpan.FromHours(duration);
    evt.Description = body;
    evt.Location = location;

    if (recurrenceDaysInterval> 0)
    {
    RecurrencePattern rp = new RecurrencePattern();
    rp.Frequency = FrequencyType.Daily;
    rp.Interval = recurrenceDaysInterval; // interval of days

    rp.Count = recurrenceCount;
    evt.AddRecurrencePattern(rp);
    }
    evt.IsAllDay = allDayEvent;

    //organizer is mandatory for outlook 2007 – think about
    // trowing an exception here.
    if (!String.IsNullOrEmpty(organizer)) evt.Organizer = organizer;

    if (!String.IsNullOrEmpty(eventId)) evt.UID = eventId;

    //”REQUEST” will update an existing event with the same
    // UID (Unique ID) and a newer time stamp.
    if (updatePreviousEvent) iCal.Method = “REQUEST”;

    // Save into calendar file.
    iCalendarSerializer serializer =
    new iCalendarSerializer(iCal);
    //serializer.Serialize(@”iCalendar.ics”);

    MailMessage msg = new MailMessage();
    msg.From = new MailAddress(“AAA@BBB.com”);
    msg.To.Add(“CCC@BBB.com”);
    msg.Subject = title;
    msg.Body = body;

    Attachment att = Attachment.CreateAttachmentFromString(serializer.SerializeToString(), new ContentType(“text/calendar”));
    att.TransferEncoding = TransferEncoding.Base64;
    att.Name = eventId + “.ics”;

    msg.Attachments.Add(att);

    SmtpClient clt = new SmtpClient(“mailhost.BBB.com”);
    try
    {
    clt.Send(msg);
    }
    catch { }

    • Hello Chris,
      Could you try changing Organizer to an Email address?
      (I would like making some tests, but we’re on holiday for the next two weeks!)

  4. Kobi,

    I have tried for Organizer = an Email address before but still a mail with attachment.

    Have a good holiday!

    • Hello Chris,
      I’ve tested your code, and it’s working well for me. I get a meeting request for both outlook and gmail.
      Have you been able to solve this issue?
      Thanks.

  5. Hi Kobi,

    Thanks for your reply, really it helped me a lot.
    But my problem is, if i send meeting request from my application, it is getting delivered as attachment in mail, but if i run the same application from other local machine it is delivered as meeting request. could you suggest me the reason for this ?

    Thank you

    • Hello Shyam Mala,
      I haven’t experienced this, my code worked for all the computers I’ve tested (though, all of the servers where Windows 2003. I’ll make another test tomorrow, on XP).
      If you do figure the cause, which could be a configuration, a network permission, or whatnot, could you please update me? I’d like to share this with more people, as some have experience what you describe.
      Thanks.

  6. hi Kobi,

    Yet I didn’t get solution for my previous post, if I find surely I will share it. Can we overwrite reminder from the application. i.e., when the meeting request is sent through the application, the default reminder is 15 min . I need to overwrite this 15 min as as 30 min or 1 hour through application. Is it possible?

    regards,
    shyamala

    • Hi Kobi,

      How can we do recurrent meeting request which is similar to outlook Recurrence functionality?

      • Hello Again Shyan,
        The code above has some basic recurrent
        I’d like to kindly forward you to DDay.iCal’s Support Forums, they have answers to most questions on the ICS format.
        Also, the code above has basic support for recurrence. For more complex patterns you may have to add more events to the same file (again, please check the documentations of DDay.iCal). Keep in mind you should test them with Outlook 2003 and 2007, they behave differently.
        Thanks.

  7. For anyone having trouble with outlook not detecting it as a meeting request you might want to try alternative views, they worked for me;

    Some sample code..

    MailMessage m = new MailMessage(new MailAddress(someone@email.com), new MailAddress(someoneelse@email.com));

    ContentType calType = new ContentType(“text/calendar”);
    calType.Parameters.Add(“method”, “REQUEST”);
    calType.Parameters.Add(“name”, “meeting.ics”);

    AlternateView htmlView = AlternateView.CreateAlternateViewFromString(body, new ContentType(“text/html”);
    AlternateView calendarView = AlternateView.CreateAlternateViewFromString(s.SerializeToString(), calType);
    calendarView.TransferEncoding = TransferEncoding.SevenBit;

    m.AlternateViews.Add(calendarView);
    m.AlternateViews.Add(htmlView);
    m.Body = body;
    sendMailMessage(m);

    where s is the iCalSerializer.

    Also note that the value you use for calType.Parameters.Add(“method”, “REQUEST”) should be the same as that inside the event you have created. i.e. iCal.Method = “REQUEST”;

    Hope that helps someone, you have no idea how many different permutations I’ve tried.

  8. Kobi,

    Is there an easy way – for a non-programmer to send an appointment and invite attendees in the body of the message instead of an attachment?

    Thank You,

    Ron

    • Hi Ron,
      Well, there are probably dozens of services that offer that – obviously Outlook if you’re working on a corporation, or Google Calendar.

  9. Thanks for the reply Kobi.

    Would you be able to tell me how to send an invitation to users in the body of the message instead of as an attachment?

    Thank You,

    Ron

    • Hello Arasi,
      There is no difference. In fact, this code is from a web service, which is definitely a web application 🙂
      It’s possible you already have an SmtpClient defined in your web.config, so you may be able to use that. Other than that, it should be good to go.

  10. Hi Kobi,
    SMTP client is not defined in web.config.

    I am new to C# and unaware of mailing procedure
    Please help me from the beginning how do i go about?
    I used your code defined web service – and it gave me some errors:

    • “SendAppointmentFromICalWithMailTitle”.
    • Unable to create an event “Event evt”
    • also I need to provide meeting end date for the request

    Please help me in this regard also

    Thanks

    • Hi Arasi: Make sure you add a reference to the dday.ical dll, and add the right “using” statements. The rest or your questioned are mentioned in the post.
      SendAppointmentFromICalWithMailTitle isn’t defined here – it’s a helper function left for implementation. I can’t really give you a step-by-step instruction, I think the tutorial id detailed enough, and it assumes you have experience with C#.
      For starters, make sure you’re able to send regular Mail Messages, then add reference to dday.ical, and it should be a few easy steps later.

  11. Thanks Kobi, this was very helpful. Also, thanks PB, the AlternateView method allowed me to see this as a request in outlook rather than an email with attachment.

  12. Hi Kobi
    I tried your code and able to send meeting requests. I am facing these two problems –

    a) Organizer is not getting the email notification for the meeting request neither the request is added in Organizer’s calender.

    b) All attendees are getting meeting request and same is added in their calender but while Accepting / Declining , notification is not sent to the organizer for the Acceptance / Rejection of the request.

    Please let me know if i am doing anything wrong. Below is my code-

    {code omitted}

    • Hello Rekhav,
      You aren’t doing anything wrong – It was never a requirement for me, so I didn’t figure out how it’s done. I guess the code isn’t complete, in a way.
      If you are able to add this, please post it here and I’ll update the code.

      By the way – one of the possible issues is that the organizer may not have the event in her calendar. It is possible outlook will misbehave.

      • Hi Kobi,
        Thanks for the reply.

        No, I m not able to add below two scenarios in your code-

        a) Setting event details in organizer’s calender.

        b) Notification to the organizer for the Acceptance / Rejection of the request from the Attendee.

        Could you please guide/suggest the way by which we can achieve this?

        Thx
        Rekhav

    • Hi Kobi,

      Isn’t there any good answer or solution to the two problems yet? I searched out similar problems on web and realize it’s really a problem because nobody can solve this problem. It’s disppointing.

      Thanks,
      Hao

      • Hello Hao,
        I’m sure there’s a solution, but I don’t really have the time to work one out – I can’t really test it at home, and I’m working on other projects at the moment. I hope the post is still useful though, at least it gives a fair starting point.

  13. I found on rfc 2447 an answer for the problem with outlook. It is the content type:

    Content-Type:text/calendar; method=request; charset=UTF-8;
    component=vevent

    so I’ve changed for:

    Attachment attachment = Attachment.CreateAttachmentFromString(
    text, new ContentType(“text/calendar; method=request; charset=UTF-8;component=vevent”));

    and now it works fine. Hope it will help someone.

  14. Is there a way to solve this organizer issue? The organizer can’t see the appointment in his calendar? Any workarounds?

    Thanks!

  15. when i create a meeting request , it is taking the central time zone. is it due to the smtp server or any other issue. my smtp server is located in nashville and i am located in arizona.

    • Hello,
      This is correct. I am missing adding a time zone to the meeting request. dday.iCal was updated since I wrote this, and handles it better. I need to look into it and updated my web service and my post, but haven’t got the time at the moment (Daylight Saving Time in Israel is a though subject).
      If you do figure it out please come back and post it here.
      Sorry, and thanks.

  16. Hello,

    Kobi, can u help me out in how to send the timezone value through , meeting request. when i add TZID value the meeting request in coming as a message.
    I really need help with timezone.

  17. Hi Kobi,
    how to get the response for a meeting request upon accept or decline.
    when ever i try to use “REPLY” method, the meeting request comes as a attachment to a email. when i open the attachment the To field is empty.

    Thanks

    • Hello Sam,
      When I get some more time, I’ll write a follow up post with regard to this issue, I also need to cover time zones, which I completely ignored here.
      Thanks.

  18. Hi Kobi

    I found this link is very useful for me. I went through your code and also the posts and answers and could send an email with calendar invitation. But still I have two problems if you could help
    1. I am trying to se the organiser in the event but I found it is not a string but DDay.iCal.Organizer . could you please advice me how to set the organiser for the event
    2. How can I auto set the event in the calendar . At the moment i have to accept the event (in me email) to see it in my calendar.

    Thanks heaps in advance
    Regards
    Erosha

  19. Look out for .Net 4 with this way of attaching events. From 3.5 to 4 if you use this you’ll find the events appears as an attachment ics files rather then an event (at least in Outlook).

    You’ll want to look at adding an AlternateView on the message itself. I followed this link and it worked well. http://www.c-sharpcorner.com/UploadFile/4cf18c/3989/

    • Jeff – Interesting. I wouldn’t expect .Net to have that effect, I’d think the version of Outlook is more important. Thanks.

  20. Hi ,
    I have a problem.I use the DDay.iCal.dll send request meeting .
    It’s going well via windows application.
    But if I send request meeting via the web application.
    The request meeting changed to the attachment,it’s not right.

  21. Everything works great except it is still shown as attachment on Outlook 2007. I added AlternateView and still outlook will not recognize it as appointment.

    I added organizer:
    evt.Organizer = new Organizer(“MAILTO:myemailaddress.com”);
    evt.Organizer.Parameters.Add(“MEMBER”, “MAILTO:myemailaddress.com”);

    Do you have any other suggestion? Google works just fine and Outlook 2003 too.

Comments are closed.