Caching ASP.NET Web API with CacheCow

本文关键字:with CacheCow API Web ASP NET Caching | 更新日期: 2023-09-27 18:13:23

我正在尝试使用CacheCow实现缓存。我有两个问题

  1. 在某些情况下,我需要手动使某些资源的缓存无效。

    例如,我有一个资源称为purchase,另一个资源称为pointMovements。它们不是完全连接的,但是在purchase上做一个帖子,意味着在pointMovement上有一些变化。Cachecow没有检测到这些变化,因为我没有调用pointmovements的API。因此,当我调用pointmovements的端点时,值被缓存,并且我无法获得新值。

    要解决这个问题,我需要手动使其无效,这是怎么可能的?

  2. 有一些控制器我不想缓存。我试图使用属性来做到这一点,但它不起作用。我在看这篇文章,但是忽略了属性。

    如何指定要缓存的控制器?

Caching ASP.NET Web API with CacheCow

我遇到了同样的问题,并找到了问题2的解决方案(无论默认设置如何禁用缓存)。

// This forces the server to not provide any caching by refreshing its cache table immediately (0 sec)
[HttpCacheRefreshPolicy(0)]
// This forces the client (browser) to not cache any data returned from the server (even if ETag is present) by setting the time-out to 0 and no-cache to true.
[HttpCacheControlPolicy(true, 0, true)]
public void MyController : ApiControler {... }

属性必须同时应用才能正常工作。您还可以通过为每个操作提供相同的规则来控制操作级别的缓存。

我还没有想出问题1的解决办法。但是请注意这里的更新。

我已经找到解决问题1的方法了。

    注册CachingHandler与您的IoC容器(在我的情况下,它是IUnityContainer)
  1. ICachingHandler注入到你的Web API控制器中。
  2. 无效资源,使用ICachingHandler.InvalidateResource(HttpRequestMessage)

请参阅下面的代码示例。该方案已经过测试。

public class Bootstrapper
{
    //...
    // Create a new caching handler and register it with the container.
    public void RegisterCache(HttpConfiguration config, IUnityContainer container)
    {
        var cachingHandler = new CachingHandler(config);
        // ...
        container.RegisterInstance<ICachingHandler>(cachingHandler);
    }
}
public class ResourceContoller : ApiController
{
    private ICachingHandler _cachingHandler;
    public ResourceContoller(ICachingHandler cachingHandler)
    {
        _cachingHandler = cachingHandler;       
    }
    [HttpPost]
    public void DeleteResource(int resourceId)
    {
        // Do the delete
        // ...
        // Now invalidate the related resource cache entry      
        // Construct a http request message to the related resource
        // HINT: The "DefaultApi" may not be your api route name, so change this to match your route.
        // GOTCHA: The route matching mechanism is case sensitive, so be aware!
        var relatedResource = new HttpRequestMessage(HttpMethod.Get, Url.Link("DefaultApi", new {controller = "linkedresource", action = "getlinkedresource", id: resourceId}));
        // Invalidate the resource with the caching handler.
        _cachingHandler.InvalidateResource(relatedResource);
    }
}

很抱歉回复晚了。

正如@Tri Q所说,这样做的方法是使用我在本博客中解释过的属性:

http://byterot.blogspot.co.uk/2013/03/rest - asp -网- wep - api - 0.4 -新特性-断裂-改变cachecow server.html

我用下面的代码解决了你的#1问题。这里我扩展了IRoutePatternProvider接口。请记住,您在GetRoutePattern中返回的内容应该与您在GetLinkedRoutePatterns中返回的内容匹配。只有这样,添加和删除才能起作用。试一试。

Inside Application_Start

CachingHandler cacheHandler = new CachingHandler(GlobalConfiguration.Configuration);
        cacheHandler.RoutePatternProvider = new CacheRoutePatternProvider();
        GlobalConfiguration.Configuration.MessageHandlers.Add(cacheHandler);

自定义类

public class CacheRoutePatternProvider : IRoutePatternProvider
{
    public string GetRoutePattern(HttpRequestMessage request)
    {
        string path = request.RequestUri.AbsolutePath;
        if (!path.EndsWith("/"))
            path += "/";
        return path;
    }
    public IEnumerable<string> GetLinkedRoutePatterns(HttpRequestMessage request)
    {
        string path = request.RequestUri.AbsolutePath;
        if(!path.EndsWith("/"))
            path += "/";
        int segmentIndex;
        // return each segment of the resource heirarchy
        while ((segmentIndex = path.LastIndexOf("/")) > 0)
        {
            path = path.Substring(0, segmentIndex);
            if(path.Contains("/api/"))
                yield return path + "/";
        }
        yield break;
    }
}