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

如何实现On the fly razor compilation并将cshtml视图存储到数据库

数据库存储动态Razor部分视图实现方案

该需求完全可实现,基于ASP.NET Core自带的自定义视图源能力+运行时Razor编译即可落地,具体实现步骤如下:

1. 基础环境配置

首先安装运行时编译依赖NuGet包:Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
在Program.cs中启用运行时编译支持:

var builder = WebApplication.CreateBuilder(args);

// 启用控制器+视图,同时添加运行时编译能力
builder.Services.AddControllersWithViews()
    .AddRazorRuntimeCompilation();

2. 自定义数据库视图提供者

核心是实现IFileProvider接口,将数据库中存储的视图模拟为Razor引擎可识别的文件资源,优先于默认的物理文件读取:

  • 首先定义数据库存储的视图结构:
public class CustomPartialView
{
    public int Id { get; set; }
    // 视图路径,需符合Razor视图寻址规则,例如 /Views/Shared/Custom/_UserDefinedPartial.cshtml
    public string ViewPath { get; set; }
    // 用户编辑的cshtml原始内容
    public string ViewContent { get; set; }
    // 最后更新时间,用于触发变更检测
    public DateTime LastModified { get; set; }
}
  • 实现自定义IFileProvider,核心逻辑:
    1. 收到视图读取请求时,优先匹配数据库中存储的ViewPath
    2. 匹配成功则返回数据库中存储的ViewContent作为文件内容
    3. 匹配失败则回退到默认物理文件提供者,读取Views文件夹下的本地cshtml文件
    4. 配套实现IChangeToken接口,监听数据库中视图的更新事件,用户修改内容后自动通知Razor引擎触发重新编译

3. 注册自定义视图提供者

在Program.cs中将自定义文件提供者注入到运行时编译配置中,确保优先读取数据库存储的视图:

builder.Services.Configure<MvcRazorRuntimeCompilationOptions>(options =>
{
    // 插入到第一位,优先级高于默认的物理文件提供者
    options.FileProviders.Insert(0, new DbViewFileProvider(builder.Configuration.GetConnectionString("DefaultDb")));
});

4. 用户编辑视图逻辑实现

用户编辑视图时,只需更新数据库对应记录的ViewContent和LastModified字段,同时触发IChangeToken的变更通知即可,无需重启服务,Razor引擎会自动完成新内容的编译,下次请求即可加载更新后的视图。

关键注意事项

  • 安全校验必须做:用户提交的cshtml内容可直接执行C#代码,需提前做语法过滤,禁止@inject、@using敏感命名空间、直接执行系统API等危险语法,避免代码注入漏洞
  • 编译错误降级:若用户提交的cshtml存在语法错误,需捕获编译异常,返回默认视图内容同时给用户明确的错误提示,避免直接抛出服务端错误
  • 性能优化:可对编译后的视图结果做缓存,缓存过期时间和视图的LastModified绑定,减少重复编译的性能消耗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:36:02