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

ASP.NET Core如何生成带动态内容的专业HTML订单邮件?

解决方案:还原邮件模板样式并动态生成订单内容

一、解决邮件样式丢失问题

邮件客户端(如Outlook、Gmail)对外部CSS、类选择器的支持非常有限,这是你使用BodyBuilder后样式与模板不符的核心原因。要还原模板效果,需做以下处理:

  1. 将模板CSS转为内联样式
    原模板的CSS多为外部或嵌入式,必须把所有样式直接写入HTML元素的style属性中。比如原模板里的表格样式,要改成:

    <table style="width:100%;border-collapse:collapse;margin-bottom:20px;">
    

    可以手动转换,也可以通过代码批量处理(遍历HTML元素,将对应类的样式写入style)。

  2. 正确使用BodyBuilder嵌入样式
    若坚持用BodyBuilder,不要引入外部CSS链接,直接将带内联样式的HTML写入HtmlContent,也可通过AddCssInline()添加全局嵌入式样式(内联样式优先级更高):

    var bodyBuilder = new BodyBuilder();
    bodyBuilder.HtmlContent = @"
    <div style='max-width:600px;margin:0 auto;font-family:Arial,sans-serif;'>
        <!-- 带内联样式的模板内容 -->
    </div>";
    

二、动态生成多笔订单内容

推荐两种灵活的实现方式:

方法1:使用Razor模板(首选)

  1. 创建Razor视图文件(如OrderEmailTemplate.cshtml),用Razor语法处理动态部分:
    @model OrderEmailModel
    <div style='max-width:600px;margin:0 auto;font-family:Arial,sans-serif;'>
        <h2 style='color:#2c3e50;'>你的订单已完成</h2>
        <table style='width:100%;border-collapse:collapse;margin-bottom:20px;'>
            <thead>
                <tr style='background:#f8f9fa;'>
                    <th style='padding:10px;text-align:left;border-bottom:1px solid #ddd;'>商品</th>
                    <th style='padding:10px;text-align:left;border-bottom:1px solid #ddd;'>数量</th>
                    <th style='padding:10px;text-align:left;border-bottom:1px solid #ddd;'>单价</th>
                    <th style='padding:10px;text-align:left;border-bottom:1px solid #ddd;'>小计</th>
                </tr>
            </thead>
            <tbody>
                @foreach(var item in Model.OrderItems)
                {
                    <tr>
                        <td style='padding:10px;border-bottom:1px solid #ddd;'>@item.ProductName</td>
                        <td style='padding:10px;border-bottom:1px solid #ddd;'>@item.Quantity</td>
                        <td style='padding:10px;border-bottom:1px solid #ddd;'>@item.Price.ToString("C")</td>
                        <td style='padding:10px;border-bottom:1px solid #ddd;'>@(item.Quantity * item.Price).ToString("C")</td>
                    </tr>
                }
            </tbody>
        </table>
        <div style='text-align:right;margin-top:20px;'>
            <p style='font-size:18px;font-weight:bold;'>总计:@Model.TotalAmount.ToString("C")</p>
        </div>
    </div>
    
  2. 在代码中渲染模板为HTML字符串(可使用RazorViewEngine或第三方库如RazorLight):
    // 构造订单数据模型
    var model = new OrderEmailModel
    {
        OrderItems = new List<OrderItem>
        {
            new OrderItem { ProductName = "商品A", Quantity = 2, Price = 99.99m },
            new OrderItem { ProductName = "商品B", Quantity = 1, Price = 199.99m }
        },
        TotalAmount = 399.97m
    };
    
    // 渲染模板得到HTML内容
    var htmlContent = RenderRazorTemplate("OrderEmailTemplate.cshtml", model);
    
    // 发送邮件
    await _emailSender.SendEmailAsync(customerEmail, "订单完成通知", htmlContent);
    

方法2:使用StringBuilder手动拼接

若不想依赖Razor,可通过StringBuilder循环生成订单行:

var sb = new StringBuilder();
// 写入模板头部(带内联样式)
sb.Append(@"
<div style='max-width:600px;margin:0 auto;font-family:Arial,sans-serif;'>
    <h2 style='color:#2c3e50;'>你的订单已完成</h2>
    <table style='width:100%;border-collapse:collapse;margin-bottom:20px;'>
        <thead>
            <tr style='background:#f8f9fa;'>
                <th style='padding:10px;text-align:left;border-bottom:1px solid #ddd;'>商品</th>
                <th style='padding:10px;text-align:left;border-bottom:1px solid #ddd;'>数量</th>
                <th style='padding:10px;text-align:left;border-bottom:1px solid #ddd;'>单价</th>
                <th style='padding:10px;text-align:left;border-bottom:1px solid #ddd;'>小计</th>
            </tr>
        </thead>
        <tbody>");

// 循环添加订单条目
foreach(var item in orderItems)
{
    sb.AppendFormat(@"
            <tr>
                <td style='padding:10px;border-bottom:1px solid #ddd;'>{0}</td>
                <td style='padding:10px;border-bottom:1px solid #ddd;'>{1}</td>
                <td style='padding:10px;border-bottom:1px solid #ddd;'>{2:C}</td>
                <td style='padding:10px;border-bottom:1px solid #ddd;'>{3:C}</td>
            </tr>",
        item.ProductName,
        item.Quantity,
        item.Price,
        item.Quantity * item.Price);
}

// 写入模板尾部
sb.Append(@"
        </tbody>
    </table>
    <div style='text-align:right;margin-top:20px;'>
        <p style='font-size:18px;font-weight:bold;'>总计:{0:C}</p>
    </div>
</div>", totalAmount);

var htmlContent = sb.ToString();
await _emailSender.SendEmailAsync(customerEmail, "订单完成通知", htmlContent);

三、额外注意事项

  • 测试邮件在主流客户端的显示效果,不同客户端对HTML/CSS支持存在差异。
  • 避免使用复杂CSS选择器(如:nth-child)、浮动布局,优先用表格布局(邮件客户端对表格支持最稳定)。
  • 模板中的图片需使用绝对路径,不要用相对路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 23:00:53