---
URL: "/zh-CN/blog/2026-06/Jasmine-Format.html"
LLMS_URL: "/zh-CN/blog/2026-06/Jasmine-Format.md"
lastUpdated: true
commentabled: true
recommended: true
title: "Jasmine.Format"
description: "一个高性能、线程安全的 .NET HTML 生成库"
date:

pageClass: "blog-page-class"
cover: "/covers/dotnet.svg"
---

---
lastUpdated: true
commentabled: true
recommended: true
title: Jasmine.Format
description: 一个高性能、线程安全的 .NET HTML 生成库
date: 2026-06-15 08:35:00
pageClass: blog-page-class
cover: /covers/dotnet.svg
---

## 引言

在 .NET 开发中，生成 HTML 内容是一个常见的需求。无论是构建邮件模板、生成报表、还是创建动态网页内容，我们都需要一种简洁、安全且高效的方式来构建 HTML。今天，我想向大家介绍 _Jasmine.Format_ —— 一个专为高性能场景设计的 .NET HTML 生成库。

## 为什么需要 Jasmine.Format？

传统的 HTML 字符串拼接方式存在以下问题：

- 安全隐患：手动拼接容易忘记 HTML 编码，导致 XSS 攻击风险
- 代码冗长：字符串拼接代码难以阅读和维护
- 性能问题：频繁的字符串分配造成 GC 压力
- 线程安全：可变对象在多线程环境下需要额外同步
- `Jasmine.Format` 旨在解决这些问题，提供一个流畅、安全、高效的 HTML 生成解决方案。

## 核心特性

### 自动 HTML 编码，防止 XSS 攻击

```CS
var p = new HtmlP().Add("<script>alert('XSS')</script>");
// 输出: <p>&lt;script&gt;alert(&#39;XSS&#39;)&lt;/script&gt;</p>
```

所有通过 `Add()` 方法添加的文本都会自动进行 HTML 编码，有效防止 XSS 攻击。只有在明确信任内容时，才使用 AddRaw() 方法。

### 流畅的 API 设计

```cs
var html = new HtmlP()
    .Add("您好，")
    .Add(new HtmlSpan("张三", "#0066cc"))
    .Add("！欢迎使用系统。")
    .WithStyle("font-size: 14px; line-height: 1.5;")
    .ToHtml();

// 输出: <p style="font-size: 14px; line-height: 1.5;">您好，<span style="color:#0066cc;">张三</span>！欢迎使用系统。</p>
```

链式方法调用让代码简洁直观，易于阅读和维护。

### 不可变模式，天然线程安全

```cs
var original = new HtmlP().Add("原始内容");
var modified = original.Add("新增内容");

// original 保持不变
Console.WriteLine(original.ToHtml());  // <p>原始内容</p>
Console.WriteLine(modified.ToHtml());  // <p>原始内容新增内容</p>
```

每次操作返回新实例，原始实例保持不变。这种不可变设计使得对象可以在多线程环境下安全共享，无需任何同步机制。

### 高性能优化

- 对象池：复用 List 对象，减少 GC 压力
- StringBuilder 缓存：线程本地缓存，提高字符串构建效率
- 容量预估：预先分配 StringBuilder 容量，避免重新分配

```cs
// 对象池配置
private static readonly ObjectPool<List<object>> _listPool =
    new ObjectPool<List<object>>(() => new List<object>(), 32);
```

### 多框架支持

支持 .NET Standard 2.0、.NET 6/7/8/9/10，可在各种 .NET 项目中使用。

## 快速入门

### 安装

```bash
dotnet add package Jasmine.Format
```

### 基础用法

#### 创建段落

```cs
using Jasmine.Format;
using Jasmine.Format.Elements.Text;
using Jasmine.Format.Elements.Basic;

// 简单段落
var p = new HtmlP().Add("Hello, World!");

// 带样式的段落
var p = new HtmlP().Add("内容").WithStyle("text-align: center;");

// 混合内容
var p = new HtmlP()
    .Add("访问 ")
    .Add(new HtmlA("示例网站", "https://example.com", "_blank"))
    .Add(" 了解更多");
```

#### 创建列表

```cs
using Jasmine.Format.Elements.List;

// 无序列表
var ul = new HtmlList(ListType.Unordered)
    .AddItem("项目一")
    .AddItem("项目二")
    .AddItem("项目三");

// 有序列表（从 5 开始）
var ol = new HtmlList(ListType.Ordered, 5)
    .AddItem("第五步")
    .AddItem("第六步");

// 批量添加
var items = new[] { "A", "B", "C" };
var ul = new HtmlList(ListType.Unordered).AddRange(items);
```

#### 创建容器

```cs
using Jasmine.Format.Elements.Container;

var div = new HtmlDiv("border: 1px solid #ccc; padding: 10px;")
    .Add(new HtmlP().Add("标题"))
    .Add(new HtmlP().Add(new HtmlSpan("高亮文本", "#ff6600")));
```

### 高级用法

#### 条件渲染

```cs
var isAdmin = true;
var p = new HtmlP()
    .Add("用户：")
    .Add(userName)
    .Add(isAdmin ? " (管理员)" : "");
```

#### 批量操作

```cs
var trains = new[] {
    new { Station = "北京", TrainNo = "G123", Status = "正常" },
    new { Station = "上海", TrainNo = "G456", Status = "晚点" }
};

var p = new HtmlP()
    .Add("列车信息：")
    .AddSpanRange(trains, t => new HtmlSpan(
        $"{t.Station}开{t.TrainNo}次",
        t.Status == "正常" ? "green" : "red"
    ));
```

#### 模板格式化

```cs
using Jasmine.Format.Utilities;

// 位置参数
var html = HtmlFormatHelper.Format(
    "欢迎 {0}, 年龄: {1}",
    "张三", "25"
);

// 命名参数
var dict = new Dictionary<string, string>
{
    { "name", "李四" },
    { "age", "30" }
};
var html = HtmlFormatHelper.FormatTemplate(
    "姓名: {name}, 年龄: {age}",
    dict
);
```

## 性能测试

在内部测试中，Jasmine.Format 在高并发场景下表现优异：

| 测试场景            | 传统字符串拼接 | Jasmine.Format  | 提升效果         |
| :------------------ | :------------- | :-------------- | :--------------- |
| **1000 次循环生成** | ~15ms          | **~8ms**        | 🚀 **~47% 更快** |
| **内存分配次数**    | ~2000 次       | **~500 次**     | 🧠 **减少 75%**  |
| **多线程并发**      | ❌ 需要同步    | ✅ **无需同步** | 🔒 **无锁设计**  |

## 实际应用场景

### 邮件模板生成

```cs
var emailBody = new HtmlDiv("font-family: Arial;")
    .Add(new HtmlP().Add($"尊敬的 {userName}："))
    .Add(new HtmlP().Add("您的订单已发货，详情如下："))
    .Add(new HtmlList(ListType.Unordered)
        .AddRange(orderItems.Select(i => $"{i.Name} - {i.Price}元")))
    .ToHtml();
```

### 报表生成

```cs
var report = new HtmlDiv()
    .Add(new HtmlP($"报告日期：{DateTime.Now:yyyy-MM-dd}").WithStyle("font-weight: bold;"))
    .Add(new HtmlList(ListType.Ordered)
        .AddRange(summaryItems))
    .ToHtml();
```

### 动态通知内容

```cs
var notification = new HtmlP()
    .Add(new HtmlSpan("系统通知", "#ff6600", "font-weight: bold;"))
    .AddRaw("<br/>")
    .Add(messageContent)
    .ToHtml();
```

## 最佳实践

- 始终使用 `Add()` 方法：除非内容完全可信，否则不要使用 `AddRaw()`
- 利用不可变性：在多线程环境下，放心共享 HtmlP、HtmlDiv 等对象
- 批量操作：使用 AddSpanRange、AddRange 等方法处理集合数据
- 样式分离：将样式集中管理，便于维护

## 总结

Jasmine.Format 提供了一种简洁、安全、高效的方式来生成 HTML 内容。它的不可变设计确保了线程安全，自动编码防止了 XSS 攻击，对象池优化提升了性能。如果你在 .NET 项目中需要生成 HTML，不妨试试 Jasmine.Format！
