.NET Framework迁移至.NET Core后,Razor页面无法自动递归解析关联文档中的模型变量
.NET Framework迁移至.NET Core后,Razor页面无法自动递归解析关联文档中的模型变量
这个问题我之前迁移项目时也碰到过,核心原因是**.NET Core的Razor视图引擎对静态资源的处理逻辑和.NET Framework不一样**——在Framework里,你的自定义Html.InlineStyle助手可能依赖了旧引擎对外部文件的隐式Razor解析,但到了Core里,静态文件(比如.css)默认不会经过Razor编译,所以里面的@Model.PrimaryColour就直接原封不动输出了。
下面给你两个可行的解决思路:
方案一:把样式文件改成Razor视图文件,让引擎自动解析
- 先把你的
document-colours.css重命名为document-colours.cshtml,内容保持不变:
:root { --key-primary: @Model.PrimaryColour; }
- 修改你的
Html.InlineStyle助手实现,让它去查找并渲染这个Razor视图,而不是直接读取静态文件内容。比如改成这样的扩展方法:
public static async Task<IHtmlContent> InlineStyleAsync(this IHtmlHelper htmlHelper, string styleViewName) { var viewEngine = htmlHelper.ViewContext.HttpContext.RequestServices.GetRequiredService<ICompositeViewEngine>(); var viewResult = viewEngine.FindView(htmlHelper.ViewContext, styleViewName, isMainPage: false); if (!viewResult.Success) { return new HtmlString($"<!-- 找不到样式视图:{styleViewName} -->"); } using var stringWriter = new StringWriter(); var viewContext = new ViewContext( htmlHelper.ViewContext, viewResult.View, htmlHelper.ViewData, htmlHelper.TempData, stringWriter, new HtmlHelperOptions() ); await viewResult.View.RenderAsync(viewContext); return new HtmlString($"<style>{stringWriter.ToString()}</style>"); }
- 在
Home.cshtml里更新调用代码:
@await Html.InlineStyleAsync("document-colours")
这样处理后,Razor引擎会先编译解析document-colours.cshtml里的模型变量,再把渲染后的样式内容内联到页面中,和你在.NET Framework里的效果一致。
方案二:手动解析样式文件中的Razor表达式(适合不想改文件后缀的场景)
如果你不想把.css改成.cshtml,可以在助手方法里手动读取文件内容后,利用当前的ViewContext来解析里面的Razor语法。不过这种方式需要额外处理Razor编译,相对麻烦一些,示例代码大概是这样:
public static async Task<IHtmlContent> InlineStyleAsync(this IHtmlHelper htmlHelper, string cssFileName) { // 读取CSS文件内容 var cssPath = Path.Combine(htmlHelper.ViewContext.HttpContext.RequestServices.GetRequiredService<IWebHostEnvironment>().ContentRootPath, "wwwroot", "css", $"{cssFileName}.css"); var rawCss = await File.ReadAllTextAsync(cssPath); // 利用Razor引擎解析内容 var serviceProvider = htmlHelper.ViewContext.HttpContext.RequestServices; var razorEngine = serviceProvider.GetRequiredService<IRazorEngine>(); var result = await razorEngine.RunCompileAsync(cssFileName, rawCss, htmlHelper.ViewData.Model); return new HtmlString($"<style>{result}</style>"); }
不过这个方案需要确保你已经引用了Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation包,并且配置了运行时编译。
总的来说,方案一更符合.NET Core的Razor设计思路,也更简单可靠,推荐优先采用。
备注:内容来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

