Использование iCal.Net для отправки приглашения на собрание для Microsoft Outlook

Я пытаюсь отправить приглашение на собрание с помощью C# и могу получить то, что я хочу, с помощью статической строки, отформатированной вручную - и вот снимок экрана того, что я смог получить со статической строкой

    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 (потому что дата и участники являются динамическими) и не может получить то, что я хочу. Пожалуйста, смотрите этот скриншот того, что я получаю с кодом ниже

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);

    }

Я не совсем уверен, что мне здесь не хватает. Информация iCalendar, сгенерированная из iCal.net, практически идентична статической строке, которую я использовал.

Спасибо!

2 ответа

Очевидно низкий регистр TRANSP: прозрачный (не TRANS:)) не беспокоит Outlook. Это было на самом деле, потому что я забыл указать свойство метода в календаре.

На основе спецификации https://www.kanzaki.com/docs/ical/method.html - "При использовании в объекте сообщения MIME значение этого свойства ДОЛЖНО совпадать со значением параметра Content-Type "method". Это свойство может появляться только один раз в объекте iCalendar. Если указано либо свойство "МЕТОД", либо параметр "метод" Content-Type, то также ДОЛЖЕН быть указан и другой. "

Я добавил строку c.Method = "REQUEST"; и это сработало, как и ожидалось.

За одним исключением - очевидно, что Outlook не нравится период в адресе электронной почты Организатора. Приглашение на собрание не будет отправлено с адресом электронной почты, например "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")
        });

Я открою другую ветку для этого, но хотел бы услышать это, если кто-то знает почему:)

В ical.net есть ошибка, когда статусы не прописные, как того требует RFC-5545. Это потому, что они являются перечислениями, а строковое имя перечисления используется во время сериализации. В этом конкретном случае, я думаю, если вы сделаете замену строки для TRANS:Transparentи в верхнем регистре (TRANS:TRANSPARENT), это должно исправить вашу проблему.

Как правило, избегайте ненужных свойств, так как это только увеличивает нагрузку на сериализацию и размер получаемого результата, поэтому не задавайте прозрачность, если она вам действительно не нужна.

Несмотря на простоту исправления, я еще не внес изменения, потому что нет способа сделать это обратно совместимым способом, который требует изменения основного номера версии ical.net. (Код клиента не должен был бы изменяться, но базовый тип enum в string, что требует от клиентов перекомпилировать свой код.)

В будущем вы можете найти валидатор icalendar.org, полезный для отслеживания ошибок, подобных этой.

Другие вопросы по тегам