Skip to content

Instantly share code, notes, and snippets.

@GeradeDev
Last active March 4, 2020 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GeradeDev/93aa4e195a43a580cda96f9bac781834 to your computer and use it in GitHub Desktop.
Save GeradeDev/93aa4e195a43a580cda96f9bac781834 to your computer and use it in GitHub Desktop.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CachedAttribute : Attribute, IAsyncActionFilter
{
private readonly int _timeToLiveSeconds;
public CachedAttribute(int timeToLiveSeconds)
{
_timeToLiveSeconds = timeToLiveSeconds;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
//Get service settings for redis
var cacheSettings = context.HttpContext.RequestServices.GetRequiredService<RedisOptions>();
if (!cacheSettings.Enabled)
{
await next();
return;
}
//Get the service, generate unique key from request
var cacheService = context.HttpContext.RequestServices.GetRequiredService<IResponseCacheService>();
var cacheKey = GenerateCacheKeyFromRequest(context.HttpContext.Request);
//get data from cache
var cachedResponse = await cacheService.GetCachedResponseAsync(cacheKey);
//return response if data found in cache
if (!string.IsNullOrEmpty(cachedResponse))
{
var contentResult = new ContentResult
{
Content = cachedResponse,
ContentType = "application/json",
StatusCode = 200
};
context.Result = contentResult;
return;
}
//else, continue along request pipeline
var executedContext = await next();
//if the result of the request is sucessful, save the response in the cache for subsequent requests
if (executedContext.Result is OkObjectResult okObjectResult)
{
await cacheService.CacheResponseAsync(cacheKey, okObjectResult.Value, TimeSpan.FromSeconds(_timeToLiveSeconds));
}
}
private static string GenerateCacheKeyFromRequest(HttpRequest request)
{
var keyBuilder = new StringBuilder();
keyBuilder.Append($"{request.Path}");
foreach (var (key, value) in request.Query.OrderBy(x => x.Key))
{
keyBuilder.Append($"|{key}-{value}");
}
return keyBuilder.ToString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment