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

C# 使用iCal.Net发送Microsoft Outlook的会议邀请,c#,icalendar,ical-dotnet,C#,Icalendar,Ical Dotnet,我正在尝试使用C#发送会议邀请,并且能够通过手动格式化的静态字符串获得我想要的内容- 这里是 我现在正试图用iCal.Net复制这一点(因为日期和与会者都是动态的),但无法得到我想要的。请看下面的代码 public static void SendICal() { DateTime dtStart = new DateTime(2017, 12, 4); DateTime dtEnd = dtStart.AddDays(1);

我正在尝试使用C#发送会议邀请,并且能够通过手动格式化的静态字符串获得我想要的内容- 这里是

我现在正试图用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信息与我使用的静态字符串几乎相同

谢谢

在ical.net中,状态不是大写的。这是因为,枚举的字符串名是序列化期间使用的名称。在这种情况下,我认为如果您对
TRANS:Transparent
和大写(
TRANS:Transparent
)进行字符串替换,应该可以解决您的问题

一般来说,避免不必要的属性,因为它只会增加序列化负担和结果输出的大小,所以除非您实际需要,否则不要指定透明度

尽管修复程序很简单,但我还没有进行更改,因为没有办法以向后兼容的方式进行更改,这是不可能的。(客户端代码不必更改,但基础类型将从
enum
变为
string
,这要求客户端重新编译其代码。)


将来,您可能会发现跟踪此类错误的方法很有用。

显然,TRANSP:Transparent(非TRANS:)的小写形式不会影响Outlook。实际上是因为我忘了在日历上指定Method属性

根据规范-“在MIME消息实体中使用时,此属性的值必须与内容类型“方法”参数值相同。此属性只能在iCalendar对象中出现一次。如果指定了“方法”属性或内容类型“方法”参数,则还必须指定另一个。”

我添加了一行
c.Method=“REQUEST”并且它按预期工作

不过有一个例外——显然Outlook不喜欢组织者电子邮件地址中的句号。会议邀请将不会以类似“song”的电子邮件地址发送。lay@company.com,如果我将其更改为slay@company.com"


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

返回到原始工作代码,实现StringBuilder或字符串连接来处理字符串测试的构造。看起来您还必须传递收件人和角色的列表。但无论哪种情况,你都必须这样做。我希望iCal.net能够帮助你格式化每行中的长字符串。iCalendar规范每行限制为75个字符。我还希望能够将文件附加到事件中,但不确定如果我使用字符串生成器路由,我该如何做。限制实际上是75个八位字节,尽管它在ical.net中实现为75个字符。对于需要超过1个字节才能显示的字符,折叠违反了规范,我应该在某个时候加以修正。无论如何,如果您好奇的话,可以在这里查看fold实现:显然TRANSP:Transparent(not TRANS:)的小写形式不会影响Outlook。实际上是因为我忘了在日历上指定Method属性。根据规范-“在MIME消息实体中使用时,此属性的值必须与内容类型“方法”参数值相同。此属性只能在iCalendar对象中出现一次。如果指定了“方法”属性或内容类型“方法”参数,则还必须指定另一个。”我添加了行
方法
根据规范是一个可选属性,但显然Outlook需要它,这有点道理,因为Outlook有特定的业务目标。很好,微软正在按预期使用该规范。在这种情况下,当ics文本中未指定内容时,Microsoft实际上会发布Outlook的行为:
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);

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