如何以编程方式获取多个视图的模型类型?
我明白你现在的困扰——分散在多个项目里的Razor视图,一个个靠字符串搜索确实麻烦,还容易因为格式、注释等问题漏判。针对你的场景(所有视图都继承自Our.Custom.TypeOfView<IModel>这类自定义基类),这里有几个比纯文本搜索更靠谱的方法:
方法1:用Roslyn静态代码分析精准提取
Roslyn是.NET官方的代码分析引擎,能真正解析Razor文件的语法结构,完全避免字符串搜索的局限性。你可以写个简单的控制台工具,遍历所有视图文件,提取@inherits指令里的泛型模型参数:
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Razor; using System.IO; var workspace = new AdhocWorkspace(); var razorEngine = RazorProjectEngine.Create(workspace.Services, RazorConfiguration.Default); // 替换成你的项目根目录路径 foreach (var cshtmlFile in Directory.EnumerateFiles("你的项目根目录", "*.cshtml", SearchOption.AllDirectories)) { var sourceText = SourceText.From(File.ReadAllText(cshtmlFile)); var razorDoc = razorEngine.Process(cshtmlFile, sourceText); var csharpSyntaxTree = await razorDoc.GetCSharpSyntaxTreeAsync(); // 查找所有@inherits指令节点 var inheritsDirectives = csharpSyntaxTree.GetRoot() .DescendantNodes() .OfType<InheritsDirectiveSyntax>(); foreach (var directive in inheritsDirectives) { // 提取泛型参数里的模型/接口 if (directive.Type is GenericNameSyntax genericType && genericType.TypeArgumentList.Arguments.Any()) { var modelType = genericType.TypeArgumentList.Arguments[0].ToString(); Console.WriteLine($"视图: {cshtmlFile} | 对应模型/接口: {modelType}"); } } }
这个方法能精准识别语法结构,哪怕视图里的@inherits指令有换行、多余空格,或者被注释的内容,都不会误判。
方法2:Visual Studio“查找所有引用”快速定位
如果你的项目已经在Visual Studio中加载完成,这是最省事的办法:
- 找到
Our.Custom.TypeOfView<T>这个泛型基类的定义 - 右键点击它,选择查找所有引用
- 在搜索结果面板里,每个视图的
@inherits指令都会被列为引用项,你能直接看到对应的泛型参数(也就是你要的IModel),还能一键跳转到对应的视图文件。
方法3:增强版正则表达式搜索(轻量替代方案)
如果暂时不想折腾Roslyn,也可以用更精准的正则表达式替代简单字符串搜索,能过滤掉注释、格式干扰:
用这个正则匹配:
@inherits\s+Our\.Custom\.TypeOfView<([^>]+)>
比如用PowerShell批量执行:
Get-ChildItem -Path "你的项目根目录" -Filter "*.cshtml" -Recurse | ForEach-Object { $content = Get-Content $_.FullName -Raw if ($content -match '@inherits\s+Our\.Custom\.TypeOfView<([^>]+)>') { Write-Host "$($_.FullName) -> $($matches[1])" } }
这个方案比纯字符串搜索靠谱,但还是不如Roslyn精准(比如无法处理复杂的嵌套泛型),适合临时快速排查。
方法4:自定义MSBuild任务(批量监控场景)
如果需要在项目构建过程中自动收集视图与模型的对应关系(比如生成文档、做依赖检查),可以写一个自定义MSBuild任务,在编译阶段遍历Razor视图并解析信息,输出到日志或指定文件中。
内容的提问来源于stack exchange,提问作者James Kraus
相关产品推荐
相关产品推荐

