C# 使用iCal.Net发送Microsoft Outlook的会议邀请
我正在尝试使用C#发送会议邀请,并且能够通过手动格式化的静态字符串获得我想要的内容- 这里是 我现在正试图用iCal.Net复制这一点(因为日期和与会者都是动态的),但无法得到我想要的。请看下面的代码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);
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")
});