Umbraco9程序化刷新模板缓存问题咨询
解决Umbraco9自定义视图更新后缓存不刷新的问题
针对外部开发者通过FTP更新/Views/CustomViews/下的.cshtml模板后,Umbraco缓存旧内容的问题,可以通过手动清除对应视图的Razor编译缓存+文件提供者刷新来实现类似保存文档模板时的缓存刷新效果,具体方案如下:
方案1:下载模板后精准清除对应视图缓存
在你的模板服务类中,注入IRazorViewEngine、IViewLocationCache和IFileProvider,添加缓存清除逻辑,在模板下载完成后触发:
步骤1:服务类中添加依赖注入和缓存清除方法
using Microsoft.AspNetCore.Mvc.ViewEngines; using Microsoft.Extensions.FileProviders; public class TemplateService { private readonly IRazorViewEngine _razorViewEngine; private readonly IViewLocationCache _viewLocationCache; private readonly IFileProvider _fileProvider; // 构造函数注入所需服务 public TemplateService(IRazorViewEngine razorViewEngine, IViewLocationCache viewLocationCache, IFileProvider fileProvider) { _razorViewEngine = razorViewEngine; _viewLocationCache = viewLocationCache; _fileProvider = fileProvider; } // 原有的TemplateExists方法,下载模板后调用ClearTemplateCache public bool TemplateExists(string templateName, bool forcereload) { bool templateFound = false; // 你的现有逻辑:检查模板是否存在,必要时通过FTP下载到/Views/CustomViews/ // 如果触发了模板重新下载,清除对应缓存 if (forcereload && templateFound) { ClearTemplateCache(templateName); } return templateFound; } // 清除指定模板的缓存 private void ClearTemplateCache(string templateName) { var viewPath = $"/Views/CustomViews/{templateName}"; // 1. 清除Razor视图位置缓存 _viewLocationCache.RemoveViewLocationCacheEntry(viewPath); // 2. 清除已编译的视图缓存(适配.NET 5+/Umbraco9的Razor编译机制) if (_razorViewEngine is IViewEngineWithCache cacheableEngine) { var compiledCacheKey = $"CompiledView:{viewPath}"; cacheableEngine.RemoveFromCache(compiledCacheKey); } // 3. 刷新物理文件提供者,确保Umbraco检测到文件变化 if (_fileProvider is PhysicalFileProvider physicalProvider) { physicalProvider.Refresh(viewPath); } } }
步骤2:在视图中调用逻辑不变,确保forcereload触发缓存清除
你的现有视图代码无需大幅修改,只要确保当forcereload为true(即触发模板重新下载)时,服务会自动清除对应缓存:
var setting = JsonConvert.DeserializeObject<CustomTemplateSettings>(Model.Value); var thetemplate = setting.templateName; var showContent = _service.TemplateExists(thetemplate, forcereload); thetemplate = "/Views/CustomViews/" + thetemplate; @if (showContent) { <partial name="@thetemplate" model="Model as ContentStructureField" /> }
方案2:全局刷新视图缓存(适合非高峰时段批量更新)
如果需要一次性刷新所有自定义视图的缓存(比如非高峰时段批量更新后),可以添加一个后台接口或按钮,触发全局视图缓存清除:
public void ClearAllCustomViewsCache() { var customViewsPath = "/Views/CustomViews/"; // 遍历所有.cshtml文件,逐个清除缓存 foreach (var file in _fileProvider.GetDirectoryContents(customViewsPath).Where(f => f.Name.EndsWith(".cshtml"))) { var viewPath = $"{customViewsPath}{file.Name}"; _viewLocationCache.RemoveViewLocationCacheEntry(viewPath); if (_razorViewEngine is IViewEngineWithCache cacheableEngine) { var compiledCacheKey = $"CompiledView:{viewPath}"; cacheableEngine.RemoveFromCache(compiledCacheKey); } } // 刷新文件提供者 if (_fileProvider is PhysicalFileProvider physicalProvider) { physicalProvider.Refresh(customViewsPath); } }
关键说明
- 该方案直接对标Umbraco保存内置模板时的缓存逻辑,仅清除目标视图的缓存,避免全局应用回收的影响。
- 仅在
forcereload触发模板下载时才清除缓存,日常访问仍利用缓存保证性能,符合你接受非高峰时段性能影响的需求。 - 适配Umbraco9基于.NET 5/6的Razor视图编译机制,无需依赖已缺失的旧版文档逻辑。
内容的提问来源于stack exchange,提问作者Steen
相关产品推荐
相关产品推荐

