ASP.NET Core 3.1 Razor Pages兼容传统.cshtml模板行为配置问询
解决方案
1. 自动添加@page指令
可以通过MSBuild构建任务实现无侵入的自动注入,不需要手动修改原有模板文件,将以下配置加入你的项目.csproj文件即可:
<Target Name="InjectPageDirectiveForTemplates" BeforeTargets="BeforeBuild"> <ItemGroup> <TemplateCshtml Include="Templates\**\*.cshtml" /> </ItemGroup> <Exec Command="powershell -Command "foreach ($f in @(TemplateCshtml)) { $c = Get-Content $f -Raw; if ($c -notmatch '^\s*@page') { Set-Content $f -Value ('@page' + [Environment]::NewLine + $c) -Encoding UTF8 } }"" Condition="'@(TemplateCshtml)' != ''" /> </Target>
该任务会在每次构建前扫描Templates目录下所有.cshtml文件,未携带@page指令的文件会自动在头部添加。如果需要运行时动态新增模板时也自动注入,可以扩展运行时编译的读取逻辑,在加载模板内容时自动插入@page头。
2. 配置.cshtml后缀路由
Razor Pages内置了路由约定配置能力,不需要手动遍历文件注册端点,在服务注册阶段添加如下配置即可:
var builder = WebApplication.CreateBuilder(args); // 注册Razor Pages服务 builder.Services.AddRazorPages() // 启用运行时编译,支持动态新增模板 .AddRazorRuntimeCompilation(opt => { // 将Templates目录加入Razor引擎的文件搜索路径 opt.FileProviders.Add(new PhysicalFileProvider( Path.Combine(builder.Environment.ContentRootPath, "Templates") )); }) // 配置路由规则 .AddRazorPagesOptions(opt => { // 仅为Templates目录下的页面添加.cshtml后缀路由 opt.Conventions.AddFolderRouteModelConvention("/Templates", model => { foreach (var selector in model.Selectors) { var routeTemplate = selector.AttributeRouteModel.Template; // 原有路由为Template/xxx,追加.cshtml后缀 selector.AttributeRouteModel.Template = $"{routeTemplate}.cshtml"; } }); }); var app = builder.Build(); // 配置静态文件,注意排除.cshtml文件避免直接返回源码 app.UseStaticFiles(); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Templates")), RequestPath = "/Templates", OnPrepareResponse = ctx => { if (ctx.File.Name.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase)) { // cshtml文件交给Razor Pages处理,静态文件中间件跳过 ctx.Context.Response.StatusCode = 404; ctx.Context.Response.ContentLength = 0; } } }); app.UseRouting(); app.UseAuthorization(); // 无需手动注册端点,Razor Pages会自动发现所有模板 app.MapRazorPages(); app.Run();
验证效果
配置完成后,/Templates/A.cshtml路径会自动映射到对应模板,模板内的相对路径引用不需要修改,动态新增的模板只要放入Templates目录,运行时编译会自动发现并生成对应路由。
内容的提问来源于stack exchange,提问作者Michael Stoll
相关产品推荐
相关产品推荐

