public virtual string MakeCacheKey(HttpActionContext context, MediaTypeHeaderValue mediaType, bool excludeQueryString = false, string[] baseKeyCacheArgs = null) { var basekey = BaseCacheKeyGeneratorWebApi.GetKey(context, baseKeyCacheArgs); var actionParameters = context.ActionArguments.Where(x => x.Value != null) .Select(x => x.Key + "=" + GetValue(x.Value)).ToArray(); // key renamed: basekey, parameters renamed actionParameters string parameters = null; if (!excludeQueryString) { var queryStringParameters = context.Request.GetQueryNameValuePairs() .Where(x => x.Key.ToLower() != "callback") .Select(x => x.Key + "=" + x.Value); var parametersCollections = actionParameters.Union(queryStringParameters); parameters = string.Join("&", parametersCollections); var callbackValue = GetJsonpCallback(context.Request); if (!string.IsNullOrWhiteSpace(callbackValue)) { var callback = "callback=" + callbackValue; if (parameters.Contains("&" + callback)) { parameters = parameters.Replace("&" + callback, string.Empty); } if (parameters.Contains(callback + "&")) { parameters = parameters.Replace(callback + "&", string.Empty); } if (parameters.Contains("-" + callback)) { parameters = parameters.Replace("-" + callback, string.Empty); } if (parameters.EndsWith("&")) { parameters = parameters.TrimEnd('&'); } } } else if (actionParameters.NotNulle()) { parameters = string.Join("&", actionParameters); } if (parameters == null) { parameters = string.Empty; } // baseKey is now separated from the rest by a ':' not a dash '-', to make the baseKey more evident string cachekey = $"{basekey}:{parameters}:{mediaType.MediaType}".ToLower(); return(cachekey); }
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); }
public string GetBaseCacheKey <T, U>(Expression <Func <T, U> > expression) { return(BaseCacheKeyGeneratorWebApi.GetKey(expression)); }
/// <summary></summary> /// <param name="context">You only need to send this in in pre WebApi 5.1 /// versions. On newer ones we can get this from the controller (controller.ActionContext).</param> /// <param name="cacheKeyActionArgs"> /// These values will be the same as what was set /// for CacheOutput(CacheArgs="..."), though here as separate strings /// (not comma separated).</param> public string GetBaseCacheKey(HttpActionContext context, params string[] cacheKeyActionArgs) { return(BaseCacheKeyGeneratorWebApi.GetKey(context, cacheKeyActionArgs)); }