6

我正在尝试使用 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);

    }

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

谢谢!

4

2 回答 2

3

显然 TRANSP:Transparent 的小写(不是 TRANS :))不会打扰 Outlook。这实际上是因为我忘记在 Calendar 上指定 Method 属性。

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

我添加了这条线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")
        });

我会为此打开另一个线程,但如果有人知道原因,我很想听听:)

于 2017-10-29T05:11:52.023 回答
0

ical.net 中有一个错误,其中状态不是RFC-5545 要求的大写。这是因为它们是 enums,而 enum 的字符串名称是在序列化过程中使用的。在这种特殊情况下,我认为如果您对TRANS:Transparent, 和大写 ( TRANS:TRANSPARENT) 进行字符串替换,这应该可以解决您的问题。

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

尽管修复很简单,但我还没有进行更改,因为无法以向后兼容的方式进行更改,这需要增加 ical.net 的主要版本号。(客户端代码不必更改,但底层类型将从enumto 变为string,这需要客户端重新编译他们的代码。)

将来,您可能会发现icalendar.org 验证器可用于跟踪此类错误。

于 2017-10-28T21:31:10.030 回答