使用iCal.Net发送Microsoft Outlook会议邀请

时间:2017-10-28 02:27:38

标签: c# icalendar ical-dotnet

我正在尝试使用C#发送会议邀请,并且能够通过手动格式化的静态字符串获得我想要的内容 - 这是Screenshot of what I was able to get with the static string

    public static void SendEmailString()
        {
            MailMessage msg = new MailMessage();
            msg.From = new MailAddress("song@company.com", "Song");
            msg.To.Add(new MailAddress("John@company.com", "John"));
            msg.Subject = "CS Inquiry";
            msg.Body = "TESTING";

            string test = @"BEGIN:VCALENDAR
            PRODID: -//Company & Com//Credit Inquiry//EN
            VERSION:2.0
            METHOD:REQUEST
            BEGIN:VEVENT
            ATTENDEE;CN=""John, Song"";ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:song@company.com
            ATTENDEE;CN=""Lay, Sean"";ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:lins@company.com
            ORGANIZER: John, Song
            DTSTART:20171205T040000Z
            DTEND:20171206T040000Z
            LOCATION:New York
            TRANSP:TRANSPARENT
            SEQUENCE:0
            UID:a16fbc2b-72fd-487f-adee-370dc349a2273asfdasd
            DTSTAMP:20171027T215051Z
            DESCRIPTION:Request for information regarding Test
            SUMMARY:Summary 
            PRIORITY: 5
            CLASS: PUBLIC
            BEGIN:VALARM
            TRIGGER:-PT1440M
            ACTION: DISPLAY
            DESCRIPTION:REMINDER
            END:VALARM
            END:VEVENT
            END:VCALENDAR
            ";

            SmtpClient sc = new SmtpClient("smtp.company.com");

            System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType("text/calendar");
            ct.Parameters.Add("method", "REQUEST");
            AlternateView avCal = AlternateView.CreateAlternateViewFromString(test, ct);
            msg.AlternateViews.Add(avCal);

            sc.Send(msg);

        }

我现在正试图用iCal.Net复制它(因为日期和参与者是动态的)并且无法获得我想要的东西。请参阅以下代码{/ 3}获取的screenshot

public static void SendICal()
    {            
        DateTime dtStart = new DateTime(2017, 12, 4);
        DateTime dtEnd = dtStart.AddDays(1);

        CalendarEvent e = new CalendarEvent()
        {
            DtStart = new CalDateTime(dtStart),
            DtEnd = new CalDateTime(dtEnd),
            DtStamp = new CalDateTime(DateTime.Now),
            IsAllDay = true,
            Sequence = 0,
            Transparency = TransparencyType.Transparent,
            Description = "Test with iCal.Net",
            Priority = 5,
            Class = "PUBLIC",
            Location = "New York",
            Summary = "Tested with iCal.Net Summary",
            Uid = Guid.NewGuid().ToString(),
            Organizer = new Organizer() {
                CommonName = "John, Song",
                Value = new Uri("mailto:song@company.com")
            } 
        };

        e.Attendees.Add(new Attendee()
        {
            CommonName = "John, Song",
            ParticipationStatus = "REQ-PARTICIPANT",
            Rsvp = true,
            Value = new Uri("mailto:song.John@company.com")
        });

        e.Attendees.Add(new Attendee()
        {
            CommonName = "John, Sean",
            ParticipationStatus = "REQ-PARTICIPANT",
            Rsvp = true,
            Value = new Uri("mailto:Johns@company.com")
        });


        Alarm alarm = new Alarm()
        {
            Action = AlarmAction.Display,
            Trigger = new Trigger(TimeSpan.FromDays(-1)),
            Summary = "Inquiry due in 1 day"                 
        };

        e.Alarms.Add(alarm);            


        Calendar c = new Calendar();

        c.Events.Add(e);


        CalendarSerializer serializer = new CalendarSerializer(new SerializationContext());            
        Console.WriteJohne(serializer.SerializeToString(c));


        MailMessage msg = new MailMessage();
        msg.From = new MailAddress("song.John@company.com", "Credit Inquiry");
        msg.To.Add(new MailAddress("song.John@company.com", "Song John"));
        msg.Subject = "CS Inquiry";



        System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType("text/calendar");
        ct.Parameters.Add("method", "REQUEST");
        AlternateView avCal = AlternateView.CreateAlternateViewFromString(serializer.SerializeToString(c), ct);
        msg.AlternateViews.Add(avCal);
        //Response.Write(str);
        // sc.ServicePoint.MaxIdleTime = 2;

        SmtpClient sc = new SmtpClient("smtp.company.com");            
        sc.Send(msg);

    }

我不确定我在这里缺少什么。从iCal.net生成的iCalendar信息几乎与我使用的静态字符串相同。

谢谢!

2 个答案:

答案 0 :(得分:1)

显然,TRANSP:透明(不是TRANS :)的低情况不会打扰Outlook。实际上是因为我忘了在Calendar上指定Method属性。

基于规范https://www.kanzaki.com/docs/ical/method.html - “在MIME消息实体中使用时,此属性的值必须与Content-Type”方法“参数值相同。此属性只能在iCalendar对象。如果指定了“METHOD”属性或Content-Type“method”参数,则还必须指定另一个参数。“

我添加了行c.Method = "REQUEST";,它按预期工作。

但有一个例外 - 显然Outlook不喜欢Organizer的电子邮件地址中的句号。会议邀请函不会发送电子邮件地址,如“song.lay@company.com”,如果我将其更改为“slay@company.com”,它将起作用

            e.Attendees.Add(new Attendee()
        {
            CommonName = "Lay, Song",
            ParticipationStatus = "REQ-PARTICIPANT",
            Rsvp = true,
            Value = new Uri("mailto:song.lay@company.com")
        });

我会为此打开另一个主题,但如果有人知道原因,我很乐意听到:)

答案 1 :(得分:0)

ical.net中有a bug,状态不是大写as RFC-5545 requires。这是因为they're enums和枚举的字符串名称是序列化期间使用的名称。在这种特殊情况下,我认为如果你对TRANS:Transparent和大写(TRANS:TRANSPARENT)进行字符串替换,这应该可以解决你的问题。

作为一般做法,避免使用不必要的属性,因为它只会增加序列化负担和结果输出的大小,因此除非您确实需要,否则不要指定透明度。

尽管修复的简单性,我还没有做出改变,因为没有办法以向后兼容的方式进行,requires bumping ical.net's major version number。 (客户端代码不必更改,但基础类型将从enum转到string,这需要客户端重新编译其代码。)

将来,您可能会发现icalendar.org validator对于跟踪此类错误非常有用。