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

如何使用MemoryStream发送带.txt附件的邮件?

解决方案:用MemoryStream生成文本并通过SendGrid发送无本地文件的邮件附件

嘿,我明白你现在卡在哪了——要把数据库里的Location数据生成文本,用内存流存着直接通过SendGrid发邮件附件,不用先存本地文件对吧?我之前也折腾过类似的需求,给你捋捋具体怎么实现:

第一步:完善MemoryStream写入文本的逻辑

你已经开始用MemoryStream了,核心是要正确把数据写入流,并且写完后重置流的位置到开头,不然后续SendGrid读取的时候会从流的末尾开始,读不到任何内容。这里用StreamWriter来处理文本写入会更方便:

private MemoryStream WriteToTextFile(IEnumerable<Location> locations)
{
    var memoryStream = new MemoryStream();
    using (var writer = new StreamWriter(memoryStream, Encoding.UTF8, leaveOpen: true))
    {
        // 可选:先写表头,让文件结构更清晰
        writer.WriteLine("ID,名称,纬度,经度");
        
        // 遍历Location数据,按格式写入每一行
        foreach (var location in locations)
        {
            // 这里用逗号分隔的格式示例,你可以根据需求调整文本格式
            writer.WriteLine($"{location.Id},{location.Name},{location.Latitude},{location.Longitude}");
        }
    }
    // 关键:重置流的位置到起始点,保证后续能读取到完整内容
    memoryStream.Position = 0;
    return memoryStream;
}

注意这里StreamWriter的leaveOpen参数设为true,这样在using块结束时不会自动关闭MemoryStream,我们才能完整返回这个流。

第二步:通过SendGrid API发送带内存流附件的邮件

接下来要把MemoryStream转换成SendGrid能识别的附件格式。SendGrid的Attachment类需要把流内容转成Base64字符串,同时指定文件名、媒体类型等关键信息:

using SendGrid;
using SendGrid.Helpers.Mail;

public async Task SendLocationEmailWithAttachment(string toEmail, IEnumerable<Location> locations)
{
    var apiKey = "你的SendGrid API密钥";
    var client = new SendGridClient(apiKey);
    
    // 生成存储文本数据的内存流
    var textStream = WriteToTextFile(locations);
    
    // 将内存流内容转换为Base64字符串(SendGrid附件要求的格式)
    string base64Content;
    using (var reader = new StreamReader(textStream))
    {
        var contentBytes = Encoding.UTF8.GetBytes(reader.ReadToEnd());
        base64Content = Convert.ToBase64String(contentBytes);
        // 再次重置流位置,避免后续复用流时出问题
        textStream.Position = 0;
    }
    
    // 创建SendGrid附件对象
    var attachment = new Attachment
    {
        Content = base64Content,
        Filename = "locations_data.txt",
        Type = "text/plain",
        Disposition = "attachment"
    };
    
    // 构建邮件基础内容
    var from = new EmailAddress("your-email@example.com", "你的名称");
    var to = new EmailAddress(toEmail);
    var subject = "最新Location数据文本";
    var plainTextContent = "请查收附件中的Location数据文件。";
    var htmlContent = "<p>请查收附件中的Location数据文件。</p>";
    
    var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
    msg.Attachments = new List<Attachment> { attachment };
    
    // 发送邮件
    var response = await client.SendEmailAsync(msg);
    // 可以根据response.StatusCode判断发送是否成功
}

关键注意点

  • 流的Position重置:每次写入或读取流之后,一定要把Position设为0,不然后续操作会从当前指针位置开始,导致数据丢失。
  • 编码一致性:写入和读取时用相同的编码(比如UTF8),避免出现乱码。
  • SendGrid附件参数:Type要设为正确的媒体类型,普通文本用text/plain,如果是CSV格式可以用text/csv;Disposition设为attachment表示作为附件发送。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:26:04