如何实现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,核心逻辑:- 收到视图读取请求时,优先匹配数据库中存储的
ViewPath - 匹配成功则返回数据库中存储的
ViewContent作为文件内容 - 匹配失败则回退到默认物理文件提供者,读取Views文件夹下的本地cshtml文件
- 配套实现
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
相关产品推荐
相关产品推荐

