You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C#创建ICS文件并发送带附件日历邮件:附件丢失求助

解决ICS日历附件丢失的邮件发送问题

嘿,我明白你现在急着解决这个问题——邮件能收到但ICS附件丢了,大概率是在生成ICS内容或者添加附件的环节踩了坑。我帮你梳理下关键问题点,再给你一个能直接用的修正版代码:

修正后的完整代码

public IHttpActionResult Cal(calendar objApptEmail)
{
    try
    {
        // 生成符合iCalendar标准的ICS内容,这是客户端能识别的核心
        string icsContent = @"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Your Company//EN
METHOD:REQUEST
BEGIN:VEVENT
UID:" + Guid.NewGuid().ToString() + @"
DTSTAMP:" + DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ") + @"
DTSTART:" + objApptEmail.StartDate.ToUniversalTime().ToString("yyyyMMddTHHmmssZ") + @"
DTEND:" + objApptEmail.EndDate.ToUniversalTime().ToString("yyyyMMddTHHmmssZ") + @"
SUMMARY:" + EscapeIcsText(objApptEmail.Subject) + @"
DESCRIPTION:" + EscapeIcsText(objApptEmail.Description) + @"
LOCATION:" + EscapeIcsText(objApptEmail.Location) + @"
ORGANIZER;CN=Your Display Name:mailto:your-sender-email@example.com
ATTENDEE;ROLE=REQ-PARTICIPANT;CN=Attendee Name:mailto:" + objApptEmail.AttendeeEmail + @"
END:VEVENT
END:VCALENDAR";

        // 将ICS内容写入内存流,注意写完后要重置流位置
        using (MemoryStream ms = new MemoryStream())
        using (StreamWriter sw = new StreamWriter(ms, System.Text.Encoding.UTF8))
        {
            sw.Write(icsContent);
            sw.Flush();
            ms.Seek(0, SeekOrigin.Begin); // 重中之重:把流指针移到开头,否则附件会是空的

            // 构建邮件
            using (MailMessage msg = new MailMessage())
            using (SmtpClient smtp = new SmtpClient("your-smtp-server", 587))
            {
                msg.From = new MailAddress("your-sender-email@example.com", "Your Display Name");
                msg.To.Add(objApptEmail.AttendeeEmail);
                msg.Subject = objApptEmail.Subject;
                msg.Body = "请查看附件中的日历邀请";

                // 添加ICS附件,设置正确的MIME类型
                Attachment icsAttachment = new Attachment(ms, "Meeting-Invite.ics", "text/calendar");
                // 标记为附件而非内联内容
                icsAttachment.ContentDisposition.Inline = false;
                msg.Attachments.Add(icsAttachment);

                // 配置SMTP服务器(根据你的实际环境调整)
                smtp.Credentials = new System.Net.NetworkCredential("your-smtp-username", "your-smtp-password");
                smtp.EnableSsl = true;

                // 发送邮件
                smtp.Send(msg);
            }
        }

        return Ok("日历邀请已成功发送!");
    }
    catch (Exception ex)
    {
        return InternalServerError(ex);
    }
}

// 辅助方法:处理ICS文本中的特殊字符,避免格式错误
private string EscapeIcsText(string text)
{
    if (string.IsNullOrEmpty(text)) return string.Empty;
    return text.Replace("\\", "\\\\")
               .Replace(";", "\\;")
               .Replace(",", "\\,")
               .Replace("\n", "\\n");
}

关键注意点(这是你之前可能遗漏的地方)

  • ICS标准必须合规:
    必须包含VCALENDAR和VEVENT核心结构,UID要唯一(用Guid生成就很稳妥),时间字段必须是UTC格式的yyyyMMddTHHmmssZ,METHOD:REQUEST是让邮件客户端识别为「邀请」的关键标识。
  • 流位置一定要重置:
    用StreamWriter写完内容后,流的指针会停在末尾,必须用ms.Seek(0, SeekOrigin.Begin)把指针移到开头,否则邮件客户端读取附件时会读到空内容。
  • MIME类型不能错:
    附件的MIME类型必须设置为text/calendar,不能用默认的application/octet-stream,否则客户端可能无法识别这是日历文件,甚至直接丢弃。
  • 特殊字符要转义:
    ICS内容里的换行、分号、逗号等特殊字符必须转义,否则会破坏ICS格式,导致客户端解析失败——我加了EscapeIcsText辅助方法来处理这个问题。

内容的提问来源于stack exchange,提问作者Raja sekhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:14:23