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

能否在运行时创建动态ASP.NET Core Razor视图与控制器文件?

运行时创建动态ASP.NET Core Razor视图与控制器的实现方案

一、直接创建文件能否被框架识别?

不行。ASP.NET Core的控制器发现机制是在应用启动时扫描已加载的程序集,运行时新增的.cs(控制器类)或.cshtml.cs(页面模型)文件不会自动被编译和加载,因此框架无法识别为有效控制器;视图文件虽是实体文件,但没有对应控制器Action的话也无法正常调用。

二、文本模板生成文件+运行时编译的可行方案

通过文本模板生成实体的.cshtml视图和控制器/页面模型代码文件,再配合动态编译加载程序集的方式,可以实现运行时渲染需求,具体步骤如下:

1. 生成实体文件

  • 视图文件:用字符串模板生成.cshtml内容,保存到项目的Views/[ControllerName]/[ActionName].cshtml路径下(符合默认视图引擎的查找规则)。示例:

    @{
        ViewData["Title"] = "动态页面";
    }
    <h1>动态生成的视图</h1>
    <p>这是通过文本模板生成的实体视图文件</p>
    

    直接将内容写入对应路径即可,默认视图引擎会自动识别。

  • 控制器/页面模型文件:生成C#代码模板,比如基础控制器类:

    using Microsoft.AspNetCore.Mvc;
    
    namespace YourAppNamespace.Controllers
    {
        public class DynamicDemoController : Controller
        {
            public IActionResult Index()
            {
                return View();
            }
        }
    }
    

    将代码保存到Controllers/DynamicDemoController.cs(或自定义目录)。

2. 动态编译并加载控制器程序集

新增的控制器代码不会自动被框架识别,需用Roslyn动态编译代码并将生成的程序集注册到应用中:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using System.Reflection;
using System.IO;

// 读取生成的控制器代码文件内容
var controllerCode = File.ReadAllText("Controllers/DynamicDemoController.cs");

// 配置编译参数,添加必要依赖引用
var compilation = CSharpCompilation.Create("DynamicControllersAssembly")
    .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
    .AddReferences(MetadataReference.CreateFromFile(typeof(Controller).Assembly.Location))
    .AddReferences(MetadataReference.CreateFromFile(typeof(IActionResult).Assembly.Location))
    .AddReferences(MetadataReference.CreateFromFile(typeof(Program).Assembly.Location)) // 引用当前应用程序集
    .AddSyntaxTrees(CSharpSyntaxTree.ParseText(controllerCode));

// 编译生成程序集
using var ms = new MemoryStream();
var emitResult = compilation.Emit(ms);

if (emitResult.Success)
{
    ms.Seek(0, SeekOrigin.Begin);
    // 加载编译后的程序集
    var assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
    // 将程序集添加到ApplicationPart,让MVC框架发现新控制器
    var part = new AssemblyPart(assembly);
    _applicationPartManager.ApplicationParts.Add(part);
    
    // 触发控制器特征重新加载(需注入IControllerFeatureProvider和ApplicationPartManager)
    var controllerFeature = new ControllerFeature();
    _controllerFeatureProvider.PopulateFeature(controllerFeature, _applicationPartManager);
}

3. 验证访问

完成上述步骤后,访问/DynamicDemo/Index即可触发新创建的控制器Action,并渲染对应的动态视图。

注意事项

  • 权限问题:应用进程需要有写入项目目录和编译代码的权限,生产环境需谨慎配置。
  • 依赖引用:编译时要确保添加所有必要的NuGet包引用(如Microsoft.AspNetCore.Mvc、System.Runtime等),否则会编译失败。
  • 性能与安全:运行时编译会带来一定性能开销,且动态生成的代码需做好安全校验,避免注入风险。
  • 缓存处理:若多次生成同名控制器,需清理旧的编译缓存或使用唯一程序集名称,避免冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 02:25:14