Razor Engine 是一種 .NET 腳本語言和引擎,主要是為文本範本開發,這跟我們在寫 ASP.NET MVC Razor 語法是一樣的,現在我想要透過 Razor 來定義 Template,透過 Data Binding 產生各種不同的結果。在調查有哪些 Razor 套件可以在 .NET 6 下運行且可以完整支援 Razor 語法,最後我選用 RazorTemplating,他骨子裡面則是使用 Razor Class Library
另外,在調查解決方案的的過程當中得知 Scriban,他似乎顯得更為輕量,但由於它是特定的語法,一般的 IDE 沒有支援它的 Instellisense,它有 Demo 頁面,有興趣的可以去看看
資料來源以 json 的欄位命名規則(小駝峰),範本也是使用此規則,有機會再來分享下
開發環境
- Windows 11
- .NET 6
- Rider 2022.1.2
RazorTemplating
支援各種應用程式
也就是說不需要寫 ASP.NET Core MVC 也是可以使用
下圖出自官網
支援功能
下圖出自官網
預先編譯
由於使用 ASP.NET Core Razor SDK 所以會將 .cshtml 文件預編譯為 <Your-Project-Name>.Views.dll
支援 DI Container
開發步驟
開始之前可能要先知道 Razor 語法
Razor syntax reference for ASP.NET Core | Microsoft Docs
新增一個 .NET Core 的 Library 專案
更改專案類別為Microsoft.NET.Sdk.Razor
在 PropertyGroup加入 <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
安裝兩個套件
dotnet add package Microsoft.AspNetCore.Mvc --version 2.2.0
dotnet add package Razor.Templating.Core --version 1.7.0
Microsoft.AspNetCore.Mvc可以讓我們編寫Razor Template 時可以享有 Intellisense
最終的專案檔內容如下:
直接複製這個內容也是可以的
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Razor.Templating.Core" Version="1.7.0" />
</ItemGroup>
</Project>
新增 Template.ConfigMap.cshtml
*.cshtml 才能有 Intellisense,這裡我用了三種資料型態 Strong、ViewData、ViewBag,你可以根據你自己的需求來調整。
@model Lab.RazorTemplate.K8sValue
apiVersion: v1
kind: ConfigMap
metadata:
name: @Model.Common.ProjectName
namespace: @Model.Common.Namespace
spec1: @ViewData["Value1"]
spec2: @ViewBag.Value2
spec3: @ViewBag.K8S_COMMON_SERVICE_NAME
新增 K8sValue
我要用強型別綁定
public class K8sValue
{
public Common Common { get; set; }
public Resource Resource { get; set; }
}
public class Common
{
public string ProjectName { get; set; }
public string Namespace { get; set; }
}
public class Resource
{
public uint CPU { get; set; }
public uint Memory { get; set; }
}
腳本替換
RazorTemplating 使用起來很簡單,就只有一個 RenderAsync方法,支援強型別和 ViewData、ViewBag 綁定,只要宣告成 Dictionary<string, object> 即可
var html = await RazorTemplateEngine.RenderAsync("/Views/ExampleView.cshtml", model, viewDataOrViewBag);
墊一層 K8sTemplateEngine
這是我個人的習慣,你也可以直接調用 RazorTemplateEngine.RenderAsync
public class K8sTemplateEngine
{
public async Task<string> RenderAsync(string templatePath,
K8sValue k8sValue,
Dictionary<string, object> k8sDynamicValue)
{
return await Razor.Templating.Core.RazorTemplateEngine.RenderAsync(templatePath,
k8sValue,
k8sDynamicValue);
}
}
運行
一切準備就緒,調用看看吧
[TestMethod]
public async Task 替換範本()
{
var templatePath = "Template.ConfigMap.cshtml";
var k8sValue = new K8sValue()
{
Common = new Common
{
ProjectName = "member-service-api",
Namespace = "member-service",
},
};
var k8sDynamicValues = new Dictionary<string, object>
{
["Value1"] = "1",
["Value2"] = "2",
["K8S_COMMON_SERVICE_NAME"] = "3",
};
var engine = new K8sTemplateEngine();
var result = await engine.RenderAsync(templatePath, k8sValue, k8sDynamicValues);
Console.WriteLine(result);
}
結果
範例位置
sample.dotblog/Template/Lab.RazorTemplate at master · yaochangyu/sample.dotblog (github.com)
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET