예제 #1
0
        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);
        }
예제 #3
0
 public string GetBaseCacheKey <T, U>(Expression <Func <T, U> > expression)
 {
     return(BaseCacheKeyGeneratorWebApi.GetKey(expression));
 }
예제 #4
0
 /// <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));
 }