Flatwhite.WebApi.OutputCacheAttribute.OnActionExecutedAsync C# (CSharp) Method

OnActionExecutedAsync() public method

Store the response to cache store, add CacheControl and Etag to response
public OnActionExecutedAsync ( System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken ) : Task
actionExecutedContext System.Web.Http.Filters.HttpActionExecutedContext
cancellationToken System.Threading.CancellationToken
return Task
        public override async Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
        {
            if (ShouldIgnoreCache(actionExecutedContext.Request.Headers.CacheControl, actionExecutedContext.Request))
            {
                return;
            }

            if ((actionExecutedContext.ActionContext.Response == null || !actionExecutedContext.ActionContext.Response.IsSuccessStatusCode) && StaleIfError == 0)
            {
                return; // Early return
            }

            var cacheControl = actionExecutedContext.Request.Headers.CacheControl;
            if (cacheControl?.Extensions != null && cacheControl.Extensions.Any(x => x.Name == WebApiExtensions.__cacheControl_flatwhite_force_refresh))
            {
                var entry = cacheControl.Extensions.First(x => x.Name == WebApiExtensions.__cacheControl_flatwhite_force_refresh);
                cacheControl.Extensions.Remove(entry);
            }

            ApplyCacheHeaders(actionExecutedContext.ActionContext.Response, actionExecutedContext.Request);

            var storedKey = (string)actionExecutedContext.Request.Properties[Global.__flatwhite_outputcache_key];
            var cacheStore = (IAsyncCacheStore)actionExecutedContext.Request.Properties[Global.__flatwhite_outputcache_store];

            if (actionExecutedContext.ActionContext.Response == null || !actionExecutedContext.ActionContext.Response.IsSuccessStatusCode)
            {
                var cacheItem = await cacheStore.GetAsync(storedKey).ConfigureAwait(false) as WebApiCacheItem;
                if (cacheItem != null && StaleIfError > 0)
                {
                    var builder = (ICacheResponseBuilder)actionExecutedContext.Request.Properties[WebApiExtensions.__webApi_outputcache_response_builder];
                    var response = builder.GetResponse(actionExecutedContext.Request.Headers.CacheControl, cacheItem, actionExecutedContext.Request);

                    if (response != null)
                    {
                        //NOTE: Override error response
                        actionExecutedContext.Response = response;
                    }
                    return;
                }
            }

            var responseContent = actionExecutedContext.Response.Content;

            if (responseContent != null)
            {
                var cacheItem = new WebApiCacheItem
                {
                    Key = storedKey,
                    Content = await responseContent.ReadAsByteArrayAsync().ConfigureAwait(false),
                    ResponseMediaType = responseContent.Headers.ContentType.MediaType,
                    ResponseCharSet = responseContent.Headers.ContentType.CharSet,
                    StoreId = cacheStore.StoreId,
                    StaleWhileRevalidate = StaleWhileRevalidate,
                    MaxAge = MaxAge,
                    CreatedTime = DateTime.UtcNow,
                    IgnoreRevalidationRequest = IgnoreRevalidationRequest,
                    StaleIfError = StaleIfError,
                    AutoRefresh = AutoRefresh
                };
                
                var strategy = (ICacheStrategy)actionExecutedContext.Request.Properties[Global.__flatwhite_outputcache_strategy];
                var invocation = GetInvocation(actionExecutedContext.ActionContext);
                var context = GetInvocationContext(actionExecutedContext.ActionContext);
                var changeMonitors = strategy.GetChangeMonitors(invocation, context);

                CreatePhoenix(invocation, cacheItem, actionExecutedContext.Request);
                
                foreach (var mon in changeMonitors)
                {
                    mon.CacheMonitorChanged += state =>
                    {
                        RefreshCache(storedKey);
                    };
                }

                actionExecutedContext.Response.Headers.ETag = new EntityTagHeaderValue($"\"{cacheItem.Key}-{cacheItem.Checksum}\"");

                var absoluteExpiration =  DateTime.UtcNow.AddSeconds(MaxAge + Math.Max(StaleWhileRevalidate, StaleIfError));
                await cacheStore.SetAsync(cacheItem.Key, cacheItem, absoluteExpiration).ConfigureAwait(false);
            }
        }

Usage Example

コード例 #1
0
        public async Task Should_remove_self_refresh_header()
        {
            // Arrange
            _request.Headers.CacheControl =
                new CacheControlHeaderValue
            {
                MaxAge     = TimeSpan.FromSeconds(10),
                Extensions = { new NameValueHeaderValue(WebApiExtensions.__cacheControl_flatwhite_force_refresh, "1") }
            };

            var att = new Flatwhite.WebApi.OutputCacheAttribute
            {
                MaxAge = 10,
                IgnoreRevalidationRequest = true,
                StaleIfError = 2,
                CacheStoreId = _store.StoreId
            };

            _actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent("{}")
            };

            // Action
            await att.OnActionExecutedAsync(_actionExecutedContext, CancellationToken.None);

            // Assert
            //await _store.Received(2).SetAsync(Arg.Any<string>(), Arg.Any<object>(), Arg.Any<DateTimeOffset>());
            Assert.IsFalse(_request.Headers.CacheControl.Extensions.Any(x => x.Name == WebApiExtensions.__cacheControl_flatwhite_force_refresh));
        }
All Usage Examples Of Flatwhite.WebApi.OutputCacheAttribute::OnActionExecutedAsync