如何使用 Razor Engine 腳本處理 Template

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

Image result for microsoft+mvp+logo