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); }
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()