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

如何将C#邮件模型映射为MS Graph API所需的不同结构列表

问题

我有一个用于绑定JSON邮件数据的模型,包含发件人、收件人、抄送、密送等字段,结构如下:

public class Email
{
    public string From { get; set; }
    public IEnumerable<Contact> To { get; set; }
    public IEnumerable<Contact> Cc { get; set; }
    public IEnumerable<Contact> Bcc { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
    public List<IFormFile> FileAttachments { get; set; }
}

public class Contact
{
    public string EmailAddress { get; set; }
}

但使用MS Graph API发送邮件时,需要转换为完全不同的列表结构,示例如下:

var message = new Message
{
    ToRecipients = new List<Recipient>
    {
        new Recipient
        {
            EmailAddress = new EmailAddress
            {
                Address = "email@email.com",
                Name = "Joen Doe",
            },
        },
        new Recipient
        {
            EmailAddress = new EmailAddress
            {
                Address = "email2@email.com",
                Name = "Jane Dane",
            },
        },
    }
};

请问如何动态将模型中的列表映射为该结构?我需要对抄送和密送采用相同的处理方式,但无法在初始化括号内嵌套foreach循环,是否需要先创建列表再赋值?


解决方案

1. 直接用LINQ转换(无需提前创建列表)

可以利用LINQ的Select方法直接将Contact集合转换为MS Graph要求的Recipient集合,无需手动循环创建列表,能直接在对象初始化器中使用:

var message = new Message
{
    Subject = email.Subject,
    // MS Graph的Body是ItemBody类型,需将字符串转换为对应结构
    Body = new ItemBody 
    { 
        Content = email.Body, 
        ContentType = BodyType.Text // 或BodyType.Html,根据需求选择
    },
    // 转换收件人列表
    ToRecipients = email.To?.Select(contact => new Recipient
    {
        EmailAddress = new EmailAddress { Address = contact.EmailAddress }
    }).ToList(),
    // 转换抄送列表
    CcRecipients = email.Cc?.Select(contact => new Recipient
    {
        EmailAddress = new EmailAddress { Address = contact.EmailAddress }
    }).ToList(),
    // 转换密送列表
    BccRecipients = email.Bcc?.Select(contact => new Recipient
    {
        EmailAddress = new EmailAddress { Address = contact.EmailAddress }
    }).ToList(),
    // 转换发件人(MS Graph的From为Recipient类型)
    From = string.IsNullOrEmpty(email.From) ? null : new Recipient
    {
        EmailAddress = new EmailAddress { Address = email.From }
    }
};

注:使用?.空传播运算符避免email.To/Cc/Bcc为null时出现空引用异常,转换后的结果通过ToList()转为List<Recipient>,符合MS Graph的类型要求。

2. 封装复用方法(避免重复代码)

因为收件人、抄送、密送的转换逻辑完全一致,封装通用方法可复用代码,让结构更清晰:

// 封装转换逻辑
private List<Recipient> MapContactsToRecipients(IEnumerable<Contact> contacts)
{
    // 若contacts为null,返回空列表而非null,避免后续调用异常
    return contacts?.Select(contact => new Recipient
    {
        EmailAddress = new EmailAddress { Address = contact.EmailAddress }
    }).ToList() ?? new List<Recipient>();
}

// 使用示例
var message = new Message
{
    Subject = email.Subject,
    Body = new ItemBody { Content = email.Body, ContentType = BodyType.Text },
    ToRecipients = MapContactsToRecipients(email.To),
    CcRecipients = MapContactsToRecipients(email.Cc),
    BccRecipients = MapContactsToRecipients(email.Bcc),
    From = string.IsNullOrEmpty(email.From) ? null : new Recipient
    {
        EmailAddress = new EmailAddress { Address = email.From }
    }
};

3. 附件的补充转换(可选)

如果需要处理模型中的FileAttachments,可以用类似方式转换为MS Graph的FileAttachment集合:

// 同步版本
message.Attachments = email.FileAttachments?.Select(file =>
{
    using var stream = file.OpenReadStream();
    var contentBytes = new byte[stream.Length];
    stream.Read(contentBytes, 0, (int)stream.Length);
    
    return new FileAttachment
    {
        Name = file.FileName,
        ContentBytes = contentBytes,
        ContentType = file.ContentType
    };
}).ToList();

// 异步版本(若在异步方法中使用)
message.Attachments = await Task.WhenAll(email.FileAttachments?.Select(async file =>
{
    using var stream = file.OpenReadStream();
    var contentBytes = new byte[stream.Length];
    await stream.ReadAsync(contentBytes, 0, (int)stream.Length);
    
    return new FileAttachment
    {
        Name = file.FileName,
        ContentBytes = contentBytes,
        ContentType = file.ContentType
    }) ?? Enumerable.Empty<Task<FileAttachment>>());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 21:35:33