-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathCachedAttribute.cs
77 lines (61 loc) · 2.42 KB
/
CachedAttribute.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Template.Core.Interfaces;
using Template.Core.Settings;
using Template.WebAPI.Extensions;
namespace Template.WebAPI.Attributes
{
[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)
{
var cacheSettings = (RedisCacheSettings)context.HttpContext.RequestServices.GetService(typeof(RedisCacheSettings));
if(!cacheSettings.Enabled)
{
await next();
return;
}
var cacheService = (IResponseCacheService)context.HttpContext.RequestServices.GetService(typeof(IResponseCacheService));
var cacheKey = GenerateCacheKeyFromRequest(context.HttpContext.Request);
var cachedResponse = await cacheService.GetCachedResponseAsync(cacheKey);
if(!string.IsNullOrEmpty(cachedResponse))
{
var contentResult = new ContentResult
{
Content = cachedResponse,
ContentType = "application/json",
StatusCode = 200
};
context.Result = contentResult;
return;
}
var executedContext = await next();
if(executedContext.Result is OkObjectResult okObjectResult)
{
await cacheService.CacheResponseAsync(cacheKey, okObjectResult.Value, TimeSpan.FromSeconds(_timeToLiveSeconds));
}
}
private static string GenerateCacheKeyFromRequest(HttpRequest request)
{
var id = request.HttpContext.GetUserId();
var keyBuilder = new StringBuilder();
keyBuilder.Append($"{request.Path}");
foreach(var (key, value) in request.Query.OrderBy(i => i.Key))
{
keyBuilder.Append($"|{id}-{key}-{value}");
}
return keyBuilder.ToString();
}
}
}