文本模板

文本模板可以理解为高级的string.Format(...),它的用途是将 数据绑定到模板的占位标记 并生成一段新文本。

示例代码

private static readonly string s_httpTemplate = @"
POST http://www.abc.com/test/callback.aspx?data={enc(data.cn)}&v={rand} HTTP/1.1
x-header1: qqqqqqqqqqqqq
x-header2: wwwwwwwwwwwww
x-xx1: {data.xx1}
x-xx2: {enc(data.xx2)}
x-xx3: {data.xx333}
x-client-app: TestApp2
x-client-reqid: {guid}
x-client-reqid32: {guid32}
x-client-url: http://www.fish-test.com/aaa/bb.aspx
Content-Type: application/json; charset=utf-8
x-null: #{xx}#
xx-guid: {rand.guid}
xx-guid32: {rand.guid32}
xx-guid36: {rand.guid36}
xx-char: {rand.char}
xx-char0: {rand.char0}
xx-char1: {rand.char1}
xx-char2: {rand.char2}
xx-char3: {rand.char3}
xx-char4: {rand.char4}
xx-char5: {rand.char5}
xx-int: {rand.int}
xx-int0: {rand.int0}
xx-int1: {rand.int1}
xx-int2: {rand.int2}
xx-int5: {rand.int5}
xx-int9: {rand.int9}
xx-int10: {rand.int10}
xx-time1: {rand.now}
xx-time2: {5秒前}
xx-time3: {5分钟前}
xx-time4: {5小时前}
xx-time5: {5天前}
xx-time6: {2月前}
xx-value01: {rand}
xx-value02: {now}
xx-value03: {昨天}
xx-value04: {今天}
xx-value05: {明天}
xx-value06: {月初}
xx-value07: {下月初}
xx-value08: {季度初}
xx-value09: {下季度初}
xx-value10: {年初}
xx-value11: {明年初}
xx-value12: {周一}
xx-value13: {下周一}
xx-local1: {LocalSetting_key1}
xx-local2: {LocalSetting_key2}
xx-local3: {LocalSetting_keyxx}

{data}
";


public void Test1()
{
    object data = new { xx1 = 223, xx2 = "abcd", cn="中文汉字~!@#$#%" };

    TextTemplate template = new TextTemplate();
    string text = template.Populate(s_httpTemplate, data.ToDictionary());

    Console2.WriteLine(text);
}

输出结果

POST http://www.abc.com/test/callback.aspx?data=%e4%b8%ad%e6%96%87%e6%b1%89%e5%ad%97%7e!%40%23%24%23%25&v=637685405048053925 HTTP/1.1
x-header1: qqqqqqqqqqqqq
x-header2: wwwwwwwwwwwww
x-xx1: 223
x-xx2: abcd
x-xx3: {data.xx333}
x-client-app: TestApp2
x-client-reqid: 87d746f2-ec14-4fff-940a-477f61b1ca67
x-client-reqid32: 33de20e3ed014faeb976b3d16c00c83b
x-client-url: http://www.fish-test.com/aaa/bb.aspx
Content-Type: application/json; charset=utf-8
x-null: #{xx}#
xx-guid: 9a6e0f34-59e3-41ee-b21b-57033b25552a
xx-guid32: 7f57af257b2a4ef7ba3fe94d61a290c8
xx-guid36: 0c49a8e4-60ca-4038-bec9-48c99fdabd59
xx-char: b
xx-char0: {rand.char0}
xx-char1: 2
xx-char2: f1
xx-char3: 7da
xx-char4: ed84
xx-char5: 67466
xx-int: 63400309
xx-int0: {rand.int0}
xx-int1: 3
xx-int2: 39
xx-int5: 88929
xx-int9: 490415950
xx-int10: 1174402031
xx-time1: 2024-01-30 16:21:30
xx-time2: 2024-01-30 16:21:25
xx-time3: 2024-01-30 16:16:30
xx-time4: 2024-01-30 11:21:30
xx-time5: 2024-01-25 16:21:30
xx-time6: 2023-11-30 16:21:30
xx-value01: 638422284904214607
xx-value02: 2024-01-30 16:21:30
xx-value03: 2024-01-29
xx-value04: 2024-01-30
xx-value05: 2024-01-31
xx-value06: 2024-01-01
xx-value07: 2024-02-01
xx-value08: 2024-01-01
xx-value09: 2024-04-01
xx-value10: 2024-01-01
xx-value11: 2025-01-01
xx-value12: 2024-01-29
xx-value13: 2024-02-05
xx-local1: abcd
xx-local2: 1234
xx-local3: {LocalSetting_keyxx}

{"xx1":223,"xx2":"abcd","cn":"中文汉字~!@#$#%"}


模板语法

{xxx} 表示一个占位替换符,在调用Populate时【可能】会被替换。

{xxx}可以支持的范围

  • {data} 表示整个数据对象的JSON序列化文本
  • {data.name} 读取数据对象的 name 属性
  • {rand} 获取一个随机数字
  • {rand.name} 获取 XRandom 支持的一个随机值,具体可参考上面的示例
  • {name} 同上,只是名称上简化了
  • {enc(...)} 先计算括号内的数据(参考上面规则),再做 UrlEncode

如果匹配失败,占位符不做替换。



数据绑定

文本模板由TextTemplate工具类来实现,可以调用 Populate 来生成结果

public sealed class TextTemplate
{
	/// <summary>
	/// 填充模板
	/// </summary>
	/// <param name="template"></param>
	/// <param name="data"></param>
	/// <returns></returns>
	public string Populate(string template, IDictionary<string, object> data)


	/// <summary>
	/// 填充模板
	/// </summary>
	/// <param name="template"></param>
	/// <param name="json"></param>
	/// <returns></returns>
	public string Populate(string template, string json)

}


关键字替换

有些场景下,仅仅需要【关键字】的替换功能,例如: 在一个SQL语句中,写上固定的 占位符

SQL示例:

select * from table1 where create_time >= '{今天}' and create_time < '{明天}' and userid = '{USERID}'

上面这个SQL语句中就定义了3个关键词:

  • 今天,例如:2023-01-01
  • 明天,例如:2023-01-02
  • USERID,例如:xxxxxxx

由于 XRandom 并不支持 {USERID} 这个【关键字】,所以需要自行实现一个,例如:

public static string GetCurrentUserId()
{
	// 例如(不能运行):return HttpPipelineContext.Get().HttpContext.User.Identity.Name;
	return "u" + DateTime.Now.Ticks.ToString();
}

在【程序启动】时注册这个【关键字】,

XRandom.RegisterValueGetter("USERID", GetCurrentUserId);

然后,在业务代码中可调用:

string sql = XRandom.FillTemplate(sqltemplate);

即可得到下面类似的SQL语句:

select * from table1 where create_time >= '2024-01-30' and create_time < '2024-01-31' and userid = 'u638422290772964811'