C# 将文件附加到iCalendar

C# 将文件附加到iCalendar,c#,.net,icalendar,mailmessage,alternateview,C#,.net,Icalendar,Mailmessage,Alternateview,我已通过SMTP正确发送iCalendar会议请求(使用下面的代码),但当我尝试附加文件时,该文件不会显示为iCalendar的一部分。在outlook中打开.ics后将其保存时,整个文件数据已被剥离 以下是我使用的代码: System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage(); msg.From = new System.Net.Mail.MailAddress("test1@test.com", "test1")

我已通过SMTP正确发送iCalendar会议请求(使用下面的代码),但当我尝试附加文件时,该文件不会显示为iCalendar的一部分。在outlook中打开.ics后将其保存时,整个文件数据已被剥离

以下是我使用的代码:

System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
msg.From = new System.Net.Mail.MailAddress("test1@test.com", "test1");
msg.To.Add(new System.Net.Mail.MailAddress("test2@test.com", "test2"));
msg.Subject = "Subject1";
msg.Body = "Body line 1\r\nBody line 2\r\nBody line 3";

System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType("text/calendar");
ct.Parameters.Add("method", "REQUEST");
ct.Parameters.Add("name", "meeting.ics");

System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine("BEGIN:VCALENDAR");

sb.AppendLine("PRODID:-/Microsoft Corporation//Outlook 15.0 MIMEDIR//EN");
sb.AppendLine("VERSION:2.0");
sb.AppendLine("METHOD:REQUEST");
sb.AppendLine("X-MS-OLK-FORCEINSPECTOROPEN:TRUE");

sb.AppendLine("BEGIN:VEVENT");

string file = "D:\\LoadedDate.xlsx";
string filename = Path.GetFileName(file);

sb.Append("ATTACH;ENCODING=BASE64;VALUE=BINARY;X-FILENAME=");
sb.Append(filename).Append(":").AppendLine(Convert.ToBase64String(File.ReadAllBytes(file), Base64FormattingOptions.InsertLineBreaks));

foreach (System.Net.Mail.MailAddress to in msg.To)
{
    sb.AppendLine(String.Format("ATTENDEE;CN=\"{0}\";RSVP=TRUE:mailto:{1}", String.IsNullOrEmpty(to.DisplayName) ? to.Address : to.DisplayName, to.Address));
}
sb.AppendLine("CLASS:PUBLIC");
sb.Append("CREATED:").AppendLine(DateTime.Now.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));
sb.Append("DESCRIPTION:").Append(msg.Body.Replace("\r\n", "\\n")).Append("\\n <<").Append(filename).AppendLine(">> \\n");

        string dt = DateTime.Now.AddHours(1).ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z");
        sb.AppendLine("DTSTART:" + dt);
        sb.AppendLine("DTSTAMP:" + dt);
        sb.AppendLine("DTEND:" + DateTime.Now.AddHours(5).ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));
        sb.AppendLine("LAST-MODIFIED:");
        sb.Append("LOCATION:").AppendLine("Location1");
        sb.AppendLine(String.Format("ORGANIZER;CN=\"{0}\":mailto:{0}", msg.From.Address));
        sb.AppendLine("PRIORITY:5");
        sb.AppendLine("SEQUENCE:0");
        sb.Append("SUMMARY;LANGUAGE=en-gb:").AppendLine(msg.Subject);
        sb.AppendLine("TRANSP:OPAQUE");

        // UID should be unique.
        sb.Append("UID:").AppendLine(Guid.NewGuid().ToString());
        sb.Append("X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\\n");
        sb.Append("<HTML>\\n").Append("<HEAD>\\n").Append("<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html\\; charset=iso-8859-1\">\\n").Append("<META NAME=\"Generator\" CONTENT=\"MS Exchange Server version 14.03.0162.000\">\\n");
        sb.Append("<TITLE>").Append(msg.Subject).Append("</TITLE>\\n");
        sb.Append("</HEAD>\\n").Append("<BODY>\\n").Append("<!--Converted from text/rtf format -->\\n\\n");
        sb.Append("<P DIR=LTR><SPAN LANG=\"en-gb\"><FONT FACE=\"Calibri\">").Append(msg.Body.Replace("\r\n", "</FONT></SPAN></P>\\n\\n<P DIR=LTR><SPAN LANG=\"en-gb\"><FONT FACE=\"Calibri\">")).Append("</FONT></SPAN></P>\\n\\n");
        sb.Append("<P DIR=LTR><SPAN LANG=\"en-gb\"><FONT FACE=\"Arial\" SIZE=2 COLOR=\"#000000\"> &lt\\;&lt\\;").Append(filename).Append("&gt\\;&gt\\; </FONT></SPAN></P>\\n\\n");
        sb.Append("</BODY>\\n").AppendLine("</HTML>");

        sb.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:BUSY");
        sb.AppendLine("X-MICROSOFT-CDO-IMPORTANCE:1");
        sb.AppendLine("X-MICROSOFT-DISALLOW-COUNTER:FALSE");
        sb.AppendLine("X-MS-OLK-AUTOFILLLOCATION:FALSE");
        sb.AppendLine("X-MS-OLK-AUTOSTARTCHECK:FALSE");
        sb.AppendLine("X-MS-OLK-CONFTYPE:0");
        sb.AppendFormat("X-MS-OLK-SENDER;CN=\"{0}\":mailto:{0}", msg.From.Address).AppendLine();

        sb.AppendLine("STATUS:TENTATIVE");
        sb.AppendLine("BEGIN:VALARM");
        sb.AppendLine("TRIGGER:-PT15M");
        sb.AppendLine("ACTION:DISPLAY");
        sb.AppendLine("DESCRIPTION:Reminder");
        sb.AppendLine("END:VALARM");
        sb.AppendLine("END:VEVENT");

        sb.AppendLine("END:VCALENDAR");

        System.Net.Mail.AlternateView av = System.Net.Mail.AlternateView.CreateAlternateViewFromString(sb.ToString(), ct);

        msg.AlternateViews.Add(av);

        System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("mailserver");
        client.Send(msg);
System.Net.Mail.MailMessage msg=new System.Net.Mail.MailMessage();
msg.From=新系统.Net.Mail.MailAddress(“test1@test.com“,“测试1”);
msg.To.Add(新的System.Net.Mail.MailAddress(“test2@test.com","测试2"),;
msg.Subject=“Subject1”;
msg.Body=“正文第1行\r\n正文第2行\r\n正文第3行”;
System.Net.Mime.ContentType ct=新的System.Net.Mime.ContentType(“文本/日历”);
添加(“方法”、“请求”);
ct.Parameters.Add(“名称”、“meeting.ics”);
System.Text.StringBuilder sb=新的System.Text.StringBuilder();
b.附录(“开始:VCALENDAR”);
sb.AppendLine(“PRODID:-/Microsoft Corporation//Outlook 15.0 MIMEDIR//EN”);
sb.AppendLine(“版本:2.0”);
sb.附录(“方法:请求”);
sb.附录(“X-MS-OLK-FORCEINSPECTOROPEN:真”);
某人加了一句话(“开始:VEVENT”);
string file=“D:\\LoadedDate.xlsx”;
字符串文件名=Path.GetFileName(文件);
sb.Append(“ATTACH;ENCODING=BASE64;VALUE=BINARY;X-FILENAME=”);
sb.Append(filename.Append(“:”).AppendLine(Convert.ToBase64String(File.ReadAllBytes(File)、Base64FormattingOptions.InsertLineBreaks));
foreach(msg.to中的System.Net.Mail.MailAddress to)
{
sb.AppendLine(String.Format(“ATTENDEE;CN=\“{0}\”;RSVP=TRUE:mailto:{1}”,String.IsNullOrEmpty(to.DisplayName)?to.Address:to.DisplayName,to.Address));
}
sb.附录(“类别:公共”);
sb.Append(“CREATED:”).AppendLine(DateTime.Now.ToUniversalTime().ToString(“yyyyMMdd\\THHmmss\\Z”);
sb.Append(“DESCRIPTION:”).Append(msg.Body.Replace(“\r\n”,“\\n”)).Append(\\n\\n”);
字符串dt=DateTime.Now.AddHours(1.ToUniversalTime().ToString(“yyyyMMdd\\THHmmss\\Z”);
sb.追加行(“DTSTART:+dt”);
sb.附录行(“DTSTAMP:+dt”);
sb.AppendLine(“DTEND:+DateTime.Now.AddHours(5.ToUniversalTime().ToString”(“yyyyMMdd\\THHmmss\\Z”);
sb.AppendLine(“最后修改:”);
sb.Append(“位置:”).AppendLine(“位置1”);
sb.AppendLine(String.Format(“组织者;CN=\“{0}\”:mailto:{0}”,msg.From.Address));
(b)附加条款(“优先权:5”);
sb.追加行(“顺序:0”);
sb.Append(“摘要;语言=en gb:”).AppendLine(msg.Subject);
sb.AppendLine(“TRANSP:不透明”);
//UID应该是唯一的。
sb.Append(“UID:”).AppendLine(Guid.NewGuid().ToString());
sb.追加(“X-ALT-DESC;FMTTYPE=text/html:\\n”);
某人追加(\\n”)。追加(\\n”)。追加(\\n”)。追加(\\n”)。追加(\\n);
sb.Append(“”).Append(msg.Subject.Append(\\n”);
某人追加(\\n”)。追加(\\n”)。追加(\\n\\n);
sb.Append(“

”).Append(msg.Body.Replace(“\r\n”),“

\\n\\n

”).Append(“

\\n\\n”); sb.Append(“

<\\;<\\”)。Append(文件名)。Append(“>\\;>\\”

\\n\\n”); sb.追加(“\\n”)。追加行(“”); sb.AppendLine(“X-MICROSOFT-CDO-BUSYSTATUS:BUSY”); sb.附录(“X-MICROSOFT-CDO-重要性:1”); sb.AppendLine(“X-MICROSOFT-DISALLOW-COUNTER:FALSE”); sb.AppendLine(“X-MS-OLK-AUTOFILLLOCATION:FALSE”); sb.附录行(“X-MS-OLK-AUTOSTARTCHECK:假”); sb.附录(“X-MS-OLK-CONFTYPE:0”); sb.AppendFormat(“X-MS-OLK-SENDER;CN=\“{0}\”:mailto:{0}”,msg.From.Address).AppendLine(); (b)附录(“状态:暂定”); 某人附言(BEGIN:VALARM); sb.附加线(“触发器:-PT15M”); 某人追加命令(“动作:显示”); sb.附录(“说明:提醒”); 某人附言(“结束:瓦勒姆”); 某人附言(“结束:VEVENT”); sb.附录(“结束:VCALENDAR”); System.Net.Mail.AlternateView av=System.Net.Mail.AlternateView.CreateAlternateView-FromString(sb.ToString(),ct); msg.AlternateViews.Add(av); System.Net.Mail.SmtpClient client=新的System.Net.Mail.SmtpClient(“邮件服务器”); client.Send(msg);
我已经看过了iCalendars()的RFC,我想我已经按照规范所说的做了一切。我猜可能是读取文件的方式有问题(Convert.ToBase64String位),或者是替代视图中缺少了一些内容(我看到其他人添加了多个视图)

我尝试过的事情:

  • 替换Convert.tobase64字符串(File.ReadAllBytes(File)), Base64格式选项。插入换行符)的 转换.tobase64字符串(文件.ReadAllBytes(文件), Base64格式化选项。无)
  • 使用System.Text.Encoding 将文件转换为BASE64(未成功)
  • 直接将文件附加到电子邮件(使用 MailMessage.Attachments),但这只会使电子邮件显示为 普通电子邮件
我还查看了sourceforge()上的DDay.iCal项目,但在附加文件时,我不知道它是如何工作的

我对此的一个要求是,该文件必须嵌入/附加到电子邮件中,不幸的是,我无法将其添加为URI

有人能帮忙吗

更新:按照arnaudq的建议,我已经实现了RFC中提到的将行包装为75个字符。生成的MIME消息如下所示:

BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 15.0 MIMEDIR//EN
VERSION:2.0
METHOD:REQUEST
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
BEGIN:VEVENT
ATTACH;ENCODING=BASE64;VALUE=BINARY;X-FILENAME=test.txt:U0ZMb2dObwlTRkxvYWR
 lZERhdGUNCjkxNzY3NC8xCTI3LzExLzIwMTIgMTg6MzANCjkxMjIwNS8xCTI3LzExLzIwMTIgM
 Tg6MzANCjkxMjI0Ni8xCTI3LzExLzIwMTIgMTg6MzANCjkxMjI1Mi8xCTI3LzExLzIwMTIgMTg
 6MzANCjkxMjQyMS8xCTI3LzExLzIwMTIgMTg6MzANCjkxMjQyMi8xCTI3LzExLzIwMTIgMTg6M
 zANCjkxNTMyMS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTQzNS8xCTI3LzExLzIwMTIgMTg6MzA
 NCjkxNTU5OS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNjc3NC8xCTI3LzExLzIwMTIgMTg6MzANC
 jkxNjk1OS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNjk2MC8xCTI3LzExLzIwMTIgMTg6MzANCjk
 xNzM2Ny8xCTI3LzExLzIwMTIgMTg6MzANCjkxNzQzNC8xCTI3LzExLzIwMTIgMTg6MzANCjkxN
 DczMS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDczMi8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc
 0My8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc0NC8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc0N
 S8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc0Ni8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc2MS8
 xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc2Mi8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc2My8xC
 TI3LzExLzIwMTIgMTg6MzANCjkxNTYzNS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTYzOC8xCTI
 3LzExLzIwMTIgMTg6MzANCjkxNTY0MC8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTY0MS8xCTI3L
 zExLzIwMTIgMTg6MzANCjkxNTY1OS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTc3Ni8xCTI3LzE
 xLzIwMTIgMTg6MzANCjkxNTc3Ny8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTc3OC8xCTI3LzExL
 zIwMTIgMTg6MzANCg==
ATTENDEE;CN="Test 1";RSVP=TRUE:mailto:test1@test.com
CLASS:PUBLIC
CREATED:20150318T095735Z
DESCRIPTION:Body line 1
 Body line 2
 Body line 3
 <<test.txt>> 
DTSTART:20150318T105735Z
DTSTAMP:20150318T105735Z
DTEND:20150318T145735Z
LAST-MODIFIED:
LOCATION:Location1
ORGANIZER;CN="test2@test.com":mailto:test2@test.com
PRIORITY:5
SEQUENCE:0
SUMMARY;LANGUAGE=en-gb:Subject1
TRANSP:OPAQUE
UID:40306717-c29a-42d1-b03e-0240a93c2ea2
X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//E
 N"><HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html\; charse
 t=iso-8859-1"><META NAME="Generator" CONTENT="MS Exchange Server version 1
 4.03.0162.000"><TITLE>Subject1</TITLE></HEAD><BODY><!--Converted from text
 /rtf format --><P DIR=LTR><SPAN LANG="en-gb"><FONT FACE="Calibri">Body lin
 e 1</FONT></SPAN></P><P DIR=LTR><SPAN LANG="en-gb"><FONT FACE="Calibri"></
 FONT></SPAN></P>Body line 2</FONT></SPAN></P><P DIR=LTR><SPAN LANG="en-gb"
 ><FONT FACE="Calibri"></FONT></SPAN></P>Body line 3<P DIR=LTR><SPAN LANG="
 en-gb"><FONT FACE="Arial" SIZE=2 COLOR="#000000"> &lt\;&lt\;test.txt&gt\;&
 gt\; </FONT></SPAN></P></BODY></HTML>
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MS-OLK-AUTOFILLLOCATION:FALSE
X-MS-OLK-AUTOSTARTCHECK:FALSE
X-MS-OLK-CONFTYPE:0
STATUS:TENTATIVE
BEGIN:VALARM
TRIGGER:-PT15M
ACTION:DISPLAY
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 15.0 MIMEDIR//EN
版本:2.0
方法:请求
X-MS-OLK-FORCEINSPECTOROPEN:正确
开始:VEVENT
贴上编码=BASE64;值=二进制;X-FILENAME=test.txt:U0ZMb2dObwlTRkxvYWR
lZERhdGUNCjkxNzY3NC8xCTI3LzExLzIwMTIgMTg6MzANCjkxMjIwNS8xCTI3LzExLzIwMTIgM
Tg6MzANCjkxMjI0Ni8xCTI3LzExLzIwMTIgMTg6MzANCjkxMjI1Mi8xCTI3LzExLzIwMTIgMTg
6MzANCjkxMjQyMS8xCTI3LzExLzIwMTIgMTg6MzANCjkxMjQyMi8xCTI3LzExLzIwMTIgMTg6M
zANCjkxNTMyMS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTQzNS8xCTI3LzExLzIwMTIgMTg6MzA
NCjkxNTU5OS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNjc3NC8xCTI3Lz
MailMessage msg = new MailMessage();
AlternateView alternate = AlternateView.CreateAlternateViewFromString(body, null, "text/html");
Stream stream = new MemoryStream(attachment.Bytes);// Bytes of file
LinkedResource resource = new LinkedResource(stream);                                                               
resource.ContentId = attachment.Name.Replace(".", "") + DateTime.Now.Ticks.ToString();
resource.ContentType.Name = attachment.Name;//Name of file              
resource.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;                               
alternate.LinkedResources.Add(resource);
msg.AlternateViews.Add(alternate);
String iCall = CreateICal();


            System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType("text/calendar");
            ct.Parameters.Add("charset", @"utf-8");
            ct.Parameters.Add("method", "REQUEST");
            AlternateView avCal = AlternateView.CreateAlternateViewFromString(iCall, ct);



            System.Net.Mime.ContentType cthtml = new System.Net.Mime.ContentType("text/html");
            cthtml.Parameters.Add("charset", @"utf-8");
            AlternateView avHtml = AlternateView.CreateAlternateViewFromString(this.mHTML, cthtml);

            mail.AlternateViews.Add(avHtml);
            mail.AlternateViews.Add(avCal);


            foreach (LinkedResource resource in arrattach)
            {
                avHtml.LinkedResources.Add(resource);
            }

            client.Send(mail);