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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 14:16:46