public override async Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
        {
            if (actionExecutedContext.ActionContext.Response == null || !actionExecutedContext.ActionContext.Response.IsSuccessStatusCode)
            {
                return;
            }

            if (!IsCachingAllowed(actionExecutedContext.ActionContext, AnonymousOnly))
            {
                return;
            }

            var cacheTime = CacheTimeQuery.Execute(DateTime.Now);

            if (cacheTime.AbsoluteExpiration > DateTime.Now)
            {
                var httpConfig        = actionExecutedContext.Request.GetConfiguration();
                var config            = httpConfig.CacheOutputConfiguration();
                var cacheKeyGenerator = config.GetCacheKeyGenerator(actionExecutedContext.Request, CacheKeyGenerator);

                var responseMediaType = actionExecutedContext.Request.Properties[CurrentRequestMediaType] as MediaTypeHeaderValue ?? GetExpectedMediaType(httpConfig, actionExecutedContext.ActionContext);
                var cachekey          = cacheKeyGenerator.MakeCacheKey(actionExecutedContext.ActionContext, responseMediaType, ExcludeQueryStringFromCacheKey);

                if (!string.IsNullOrWhiteSpace(cachekey) && !(_webApiCache.Contains(cachekey)))
                {
                    SetEtag(actionExecutedContext.Response, CreateEtag(actionExecutedContext, cachekey, cacheTime));

                    var responseContent = actionExecutedContext.Response.Content;

                    if (responseContent != null)
                    {
                        var    baseKey     = config.MakeBaseCachekey(actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerType.FullName, actionExecutedContext.ActionContext.ActionDescriptor.ActionName);
                        var    contentType = responseContent.Headers.ContentType;
                        string etag        = actionExecutedContext.Response.Headers.ETag.Tag;
                        //ConfigureAwait false to avoid deadlocks
                        var content = await responseContent.ReadAsByteArrayAsync().ConfigureAwait(false);

                        responseContent.Headers.Remove("Content-Length");

                        _webApiCache.Add(baseKey, string.Empty, cacheTime.AbsoluteExpiration);
                        _webApiCache.Add(cachekey, content, cacheTime.AbsoluteExpiration, baseKey);


                        _webApiCache.Add(cachekey + Constants.ContentTypeKey,
                                         contentType,
                                         cacheTime.AbsoluteExpiration, baseKey);


                        _webApiCache.Add(cachekey + Constants.EtagKey,
                                         etag,
                                         cacheTime.AbsoluteExpiration, baseKey);
                    }
                }
            }

            ApplyCacheHeaders(actionExecutedContext.ActionContext.Response, cacheTime);
        }
        private async Task OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext.ActionContext.Response == null || !actionExecutedContext.ActionContext.Response.IsSuccessStatusCode)
            {
                return;
            }

            if (!_isCachingAllowed(actionExecutedContext.ActionContext, AnonymousOnly))
            {
                return;
            }

            var cacheTime = CacheTimeQuery.Execute(DateTime.Now);

            if (cacheTime.AbsoluteExpiration > DateTime.Now)
            {
                var config            = actionExecutedContext.Request.GetConfiguration().CacheOutputConfiguration();
                var cacheKeyGenerator = config.GetCacheKeyGenerator(actionExecutedContext.Request, CacheKeyGenerator);

                var cachekey = cacheKeyGenerator.MakeCacheKey(actionExecutedContext.ActionContext, _responseMediaType, ExcludeQueryStringFromCacheKey);

                if (!string.IsNullOrWhiteSpace(cachekey) && !(_webApiCache.Contains(cachekey)))
                {
                    SetEtag(actionExecutedContext.Response, Guid.NewGuid().ToString());

                    if (actionExecutedContext.Response.Content != null)
                    {
                        var    baseKey                = config.MakeBaseCachekey(actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerName, actionExecutedContext.ActionContext.ActionDescriptor.ActionName);
                        var    contentType            = actionExecutedContext.Response.Content.Headers.ContentType;
                        string etag                   = actionExecutedContext.Response.Headers.ETag.Tag;
                        ContentRangeHeaderValue range = actionExecutedContext.Response.Content.Headers.ContentRange;
                        //ConfigureAwait false to avoid deadlocks
                        var content = await actionExecutedContext.Response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);


                        _webApiCache.Add(baseKey, string.Empty, cacheTime.AbsoluteExpiration);
                        _webApiCache.Add(cachekey, content, cacheTime.AbsoluteExpiration, baseKey);


                        _webApiCache.Add(cachekey + Constants.ContentTypeKey,
                                         contentType,
                                         cacheTime.AbsoluteExpiration, baseKey);


                        _webApiCache.Add(cachekey + Constants.EtagKey,
                                         etag,
                                         cacheTime.AbsoluteExpiration, baseKey);

                        _webApiCache.Add(cachekey + Constants.ContentRangeKey,
                                         range,
                                         cacheTime.AbsoluteExpiration, baseKey);
                    }
                }
            }

            ApplyCacheHeaders(actionExecutedContext.ActionContext.Response, cacheTime);
        }
        private async Task OnActionExecuted(HttpActionExecutedContext axctxt)
        {
            var ctxt = axctxt.ActionContext;

            if (ctxt.Response == null || !ctxt.Response.IsSuccessStatusCode)
            {
                return;
            }

            if (!_isCachingAllowed(ctxt, AnonymousOnly))
            {
                return;
            }

            var cacheTime = CacheTimeQuery.Execute(DateTime.Now);

            if (cacheTime.AbsoluteExpiration > DateTime.Now)
            {
                var config            = axctxt.Request.GetConfiguration().CacheOutputConfiguration();
                var cacheKeyGenerator = config.GetCacheKeyGenerator(axctxt.Request, CacheKeyGenerator);

                string cachekey = cacheKeyGenerator.MakeCacheKey(ctxt, _responseMediaType, ExcludeQueryStringFromCacheKey, BaseKeyCacheArgs);

                if (!string.IsNullOrWhiteSpace(cachekey) && !(_webApiCache.Contains(cachekey)))
                {
                    byte[] content = axctxt.Response.Content == null
                        ? null
                        : await axctxt.Response.Content.ReadAsByteArrayAsync();

                    string etag = !HashContentForETag || content.IsNulle()
                        ? Guid.NewGuid().ToString()
                        : GetMD5Hash(content);

                    SetEtag(axctxt.Response, etag);

                    if (axctxt.Response.Content != null)
                    {
                        string baseKey = BaseCacheKeyGeneratorWebApi.GetKey(ctxt, BaseKeyCacheArgs);

                        _webApiCache.Add(baseKey, string.Empty, cacheTime.AbsoluteExpiration);
                        _webApiCache.Add(cachekey, content, cacheTime.AbsoluteExpiration, baseKey);

                        _webApiCache.Add(cachekey + Constants.ContentTypeKey,
                                         axctxt.Response.Content.Headers.ContentType.MediaType,
                                         cacheTime.AbsoluteExpiration, baseKey);

                        _webApiCache.Add(cachekey + Constants.EtagKey,
                                         axctxt.Response.Headers.ETag.Tag,
                                         cacheTime.AbsoluteExpiration, baseKey);
                    }
                }
            }
            ApplyCacheHeaders(ctxt.Response, cacheTime);
        }
        /// <summary>
        /// Classe para pegar o cache
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cache"></param>
        /// <param name="key"></param>
        /// <param name="expiry"></param>
        /// <param name="resultGetter"></param>
        /// <param name="bypassCache"></param>
        /// <returns></returns>
        public static T GetCachedResult <T>(this IApiOutputCache cache, string key, DateTimeOffset expiry, Func <T> resultGetter, bool bypassCache = true) where T : class
        {
            var result = cache.Get <T>(key);

            if (result == null || bypassCache)
            {
                result = resultGetter();
                if (result != null)
                {
                    cache.Add(key, result, expiry);
                }
            }

            return(result);
        }
Beispiel #5
0
        public override async Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
        {
            log4net.LogManager.GetLogger(this.GetType()).Info("start: OnActionExecutedAsync");

            if (CustomTimeSpanMethodClassType != null)
            {
                MambaDefinedShortTime mambaDefinedShortTimeObject = null;

                var requestLocalPath = actionExecutedContext.Request.RequestUri.LocalPath;

                mambaDefinedShortTimeObject = _mambaDefinedShortTimeObjects.FirstOrDefault(x => string.Compare(x.Key, requestLocalPath, true) == 0).Value;
                if (mambaDefinedShortTimeObject == null)
                {
                    if (string.IsNullOrWhiteSpace(CustomTimeSpanMethodName))
                    {
                        CustomTimeSpanMethodName = _defaultCustomTimeSpanMethodName;
                    }
                    var methodInfo = CustomTimeSpanMethodClassType.GetMethod(CustomTimeSpanMethodName);
                    if (methodInfo != null)
                    {
                        mambaDefinedShortTimeObject = new MambaDefinedShortTime(actionExecutedContext, methodInfo);
                        _mambaDefinedShortTimeObjects.Add(requestLocalPath, mambaDefinedShortTimeObject);
                    }
                }

                if (mambaDefinedShortTimeObject != null)
                {
                    var _cacheTimeQuery = this.GetType().GetField("CacheTimeQuery", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                    _cacheTimeQuery.SetValue(this, mambaDefinedShortTimeObject);
                }
            }

            //Copy&Paste the OnActionExecutedAsync, instead of calling base.OnActionExecutedAsync(), because of [*]
            #region Copy&Paste from CacheOutputAttribute, as is

            if (actionExecutedContext.ActionContext.Response == null || !actionExecutedContext.ActionContext.Response.IsSuccessStatusCode)
            {
                return;
            }

            if (!IsCachingAllowed(actionExecutedContext.ActionContext, AnonymousOnly))
            {
                return;
            }

            var cacheTime = CacheTimeQuery.Execute(DateTime.UtcNow);
            if (cacheTime.AbsoluteExpiration > DateTime.UtcNow || ExpirationMode == ExpirationMode.None)
            {
                var httpConfig = actionExecutedContext.Request.GetConfiguration();
                var config     = httpConfig.CacheOutputConfiguration();

                var cacheKeyGenerator = config.GetCacheKeyGenerator(actionExecutedContext.Request, typeof(CustomCacheKeyGenerator));
                if (cacheKeyGenerator is CustomCacheKeyGenerator)
                {
                    ((CustomCacheKeyGenerator)cacheKeyGenerator).CachePerUser = CachePerUser;
                    ((CustomCacheKeyGenerator)cacheKeyGenerator).ApiName      = ApiName;
                    ((CustomCacheKeyGenerator)cacheKeyGenerator).HeadersToInlcudeInCacheKey = HeadersToInlcudeInCacheKey;
                }

                var responseMediaType = actionExecutedContext.Request.Properties[CurrentRequestMediaType] as MediaTypeHeaderValue ?? GetExpectedMediaType(httpConfig, actionExecutedContext.ActionContext);
                var cachekey          = cacheKeyGenerator.MakeCacheKey(actionExecutedContext.ActionContext, responseMediaType, ExcludeQueryStringFromCacheKey);

                // Why do we check if it already exists in cache?
                //if (!string.IsNullOrWhiteSpace(cachekey) && !(_webApiCache.Contains(cachekey)))
                if (!string.IsNullOrWhiteSpace(cachekey))
                {
                    SetEtag(actionExecutedContext.Response, CreateEtag(actionExecutedContext, cachekey, cacheTime));

                    var responseContent = actionExecutedContext.Response.Content;

                    if (responseContent != null)
                    {
                        var    baseKey     = config.MakeBaseCachekey(actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerType.FullName, actionExecutedContext.ActionContext.ActionDescriptor.ActionName);
                        var    contentType = responseContent.Headers.ContentType;
                        string etag        = actionExecutedContext.Response.Headers.ETag.Tag;

                        var content = await responseContent.ReadAsByteArrayAsync();//.ConfigureAwait(false);  [*]

                        responseContent.Headers.Remove("Content-Length");

                        if (_webApiCache is CustomCacheProvider)
                        {
                            ((CustomCacheProvider)_webApiCache).ExpirationTimeSpan = cacheTime.ClientTimeSpan;
                        }

                        _webApiCache.Add(baseKey, string.Empty, cacheTime.AbsoluteExpiration);
                        _webApiCache.Add(cachekey, content, cacheTime.AbsoluteExpiration, baseKey);


                        _webApiCache.Add(cachekey + Constants.ContentTypeKey,
                                         contentType,
                                         cacheTime.AbsoluteExpiration, baseKey);


                        _webApiCache.Add(cachekey + Constants.EtagKey,
                                         etag,
                                         cacheTime.AbsoluteExpiration, baseKey);
                    }
                }
            }

            ApplyCacheHeaders(actionExecutedContext.ActionContext.Response, cacheTime);
            #endregion

            log4net.LogManager.GetLogger(this.GetType()).Info("end: OnActionExecutedAsync");
        }// end OnActionExecutedAsync()