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

.NET Core中如何从Razor Engine模板提取Model键列表?

提取Razor模板中@Model的属性键列表

方法一:正则表达式(快速实现,适合简单模板)

对于结构相对简单的模板,可通过正则表达式匹配所有@Model.开头的属性访问,同时排除方法调用类的场景(如@Model.DoSomething())。

正则表达式与提取代码

using System.Text.RegularExpressions;
using System.Linq;

string template = @"<acord>
  <student>
     <firstName>@Model.StudentFirstName</firstName>
     <lastName>@Model.StudentLastName</lastName>
     @if(@Model.StudentPhone != null)
     {
        <phone>@Model.StudentPhone</phone>
     }
  </student>
  <parents>
     <firstName>@Model.parentFirstName</firstName>
     <lastName>@Model.parentLastName</lastName>
  </parents>
</acord>";

// 匹配@Model.后接合法C#标识符,排除方法调用
var regex = new Regex(@"@Model\.([a-zA-Z_][a-zA-Z0-9_]+)(?!\()", RegexOptions.Compiled);
var matches = regex.Matches(template);

// 去重并整理结果
var modelKeys = matches.Cast<Match>()
                       .Select(m => $"@Model.{m.Groups[1].Value}")
                       .Distinct()
                       .ToList();

// 输出提取的键
foreach (var key in modelKeys)
{
    Console.WriteLine(key);
}

这种方法优点是实现成本低,但无法处理复杂Razor语法(如嵌套属性@Model.Parent.Child、注释中的@Model引用等)。

方法二:Razor语法树解析(精准可靠,适合复杂模板)

如果模板包含条件判断、循环、嵌套属性等复杂逻辑,推荐使用官方Razor解析API生成语法树,遍历节点精准提取所有Model属性访问。

步骤1:安装依赖包

安装Microsoft.AspNetCore.Razor.Language NuGet包:

Install-Package Microsoft.AspNetCore.Razor.Language

步骤2:解析模板的代码实现

using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Collections.Generic;
using System.Linq;

public static List<string> ExtractModelProperties(string razorTemplate)
{
    var modelKeys = new HashSet<string>();
    var engine = RazorEngine.Create();
    var projectEngine = engine.Project.Create();

    // 生成Razor文档并处理为中间节点
    var document = projectEngine.CreateDocument("template.cshtml", razorTemplate);
    var intermediateNode = projectEngine.Process(document).GetIntermediateNode();

    // 递归遍历语法树节点
    TraverseNode(intermediateNode, modelKeys);
    return modelKeys.OrderBy(k => k).ToList();
}

private static void TraverseNode(IntermediateNode node, HashSet<string> modelKeys)
{
    if (node is CSharpCodeIntermediateNode codeNode)
    {
        // 解析C#代码片段,查找Model的成员访问表达式
        var syntaxTree = Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(codeNode.Code);
        var root = syntaxTree.GetRoot();

        var memberAccesses = root.DescendantNodes()
                                 .OfType<MemberAccessExpressionSyntax>()
                                 .Where(m => m.Expression is IdentifierNameSyntax identifier
                                             && identifier.Identifier.Text == "Model");

        foreach (var access in memberAccesses)
        {
            // 处理嵌套属性,拼接完整路径
            var pathSegments = new List<string> { "Model" };
            var current = access;
            while (current != null)
            {
                pathSegments.Insert(1, current.Name.Identifier.Text);
                current = current.Expression as MemberAccessExpressionSyntax;
            }
            modelKeys.Add($"@{string.Join(".", pathSegments)}");
        }
    }

    // 递归处理子节点
    foreach (var child in node.Children)
    {
        TraverseNode(child, modelKeys);
    }
}

使用示例

var template = @"<acord>
  <student>
     <firstName>@Model.StudentFirstName</firstName>
     <lastName>@Model.StudentLastName</lastName>
     @if(@Model.StudentPhone != null)
     {
        <phone>@Model.StudentPhone</phone>
     }
  </student>
  <parents>
     <firstName>@Model.parentFirstName</firstName>
     <lastName>@Model.parentLastName</lastName>
     <address>@Model.Parent.Address.Street</address>
  </parents>
</acord>";

var keys = ExtractModelProperties(template);
foreach (var key in keys)
{
    Console.WriteLine(key);
}

该方法能精准处理各种复杂Razor语法场景,是生产环境的可靠选择。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 05:39:18