Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching ASP.NET Web API with CacheCow

I am trying to implement caching using CacheCow. I have two problems:

  1. In some cases I need to invalidate manually the cache of some resources.

    For example, I have a resource that it is called purchase, and other that is called pointMovements. They are not totally connected, but doing a post in purchase, implies some changes in pointMovement. Cachecow is not detecting these changes because I am not calling the API of pointmovements. So when I call the endpoint of pointmovements, the values are cached and I cannot get the new values.

    To solve this, I need to invalidate that manually, how is that possible?

  2. There are some controllers that I don't want to cache. I am trying to use attributes for doing that but it is not working. I am following this article but the attributes are ignored.

    How can I specify which controllers to cache?

like image 658
jvrdelafuente Avatar asked Jul 18 '14 07:07

jvrdelafuente


People also ask

Is caching possible in Web API?

Caching is very common to make applications performant and scalable. If a result is already computed by the application, it is cached in a store so that next time when the same request comes, cached result can be fetched instead of processing the request again.

How do I use ETag in Web API?

First, you retrieve the current entity data by using a GET request that includes the If-Match request header. The ETag information is returned along with the entity content. Then, you send a PUT update request that includes the If-Match request header with the ETag information from the previous GET request.

What are the different caching techniques available in .NET core?

ASP.NET Core uses two caching techniques. In-memory caching uses the server memory to store cached data locally, and distributed caching distributes the cache across various servers. We'll explore them both below.


2 Answers

I came across the same set of problems and found a solution for problem 2 (disable caching regardless of the default settings).

// 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 {... }

The attributes must be applied together for this to work. You can also control the caching at the action level by providing the same rules to each action.

I've still to figure out the solution for problem 1. but watch this space for updates.

Update I have found a solution to problem 1.

  1. Register the CachingHandler with your IoC container (in my case it's IUnityContainer)
  2. Inject the ICachingHandler into your Web API controller.
  3. To invalidate the resource, use ICachingHandler.InvalidateResource(HttpRequestMessage)

Please see a code example below. The solution has been tested.

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);
    }
}
like image 129
Tri Q Tran Avatar answered Oct 22 '22 00:10

Tri Q Tran


Sorry for the late response.

As @Tri Q said, the way to do this is to use attributes which I have explained in this blog:

http://byterot.blogspot.co.uk/2013/03/rest-asp-net-wep-api-0.4-new-features-breaking-change-cachecow-server.html

like image 4
Aliostad Avatar answered Oct 22 '22 02:10

Aliostad