private string ComputeCacheKey(ActionExecutingContext filterContext) { // Assumptions: empty param values & order of params are irrelevant; optimize by sorting and removing empties var context = filterContext.HttpContext; var request = context.Request; var url = request.Url; var keyBuilder = new StringBuilder(); if (VaryByHost) { keyBuilder.AppendFormat("host_{0}", url.Authority); } var userKey = IsAnonymous(filterContext) ? "-1" : context.User.Identity.Name.GetHashCode().ToString(); if (VaryByUser) { keyBuilder.AppendFormat("u_{0}", userKey); } if (VaryByAjax) { keyBuilder.AppendFormat("ajax_{0}", filterContext.HttpContext.Request.IsAjaxRequest().GetHashCode()); } foreach (var pair in filterContext.RouteData.Values.Where(p => p.Value != null).OrderBy(p => p.Key)) { keyBuilder.AppendFormat("rd{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode()); } foreach (var pair in filterContext.ActionParameters.Where(p => p.Value != null).OrderBy(p => p.Key)) { keyBuilder.AppendFormat("ap{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode()); } if (!String.IsNullOrEmpty(VaryByCookie) && VaryByCookie != "none") { string[] cookienames = { }; if (VaryByCookie == "*") { cookienames = request.Cookies.AllKeys; } else if (!String.IsNullOrEmpty(VaryByCookie)) { cookienames = VaryByCookie.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); } IEnumerable <HttpCookie> cookies = cookienames .Where(c => !String.IsNullOrEmpty(c) && request.Cookies[c] != null && !String.IsNullOrEmpty(request.Cookies[c].Value)) .Select(c => request.Cookies[c]) .OrderBy(c => c.Name); foreach (var cookie in cookies) { keyBuilder.AppendFormat("c{0}_{1}_", cookie.Name.GetHashCode(), cookie.Value.GetHashCode()); } } if (!String.IsNullOrEmpty(VaryByQueryString) && VaryByQueryString != "none") { string[] paramnames = { }; if (VaryByQueryString == "*") { paramnames = request.QueryString.AllKeys; } else if (!String.IsNullOrEmpty(VaryByQueryString)) { paramnames = VaryByQueryString.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); } paramnames = paramnames .Where(p => !String.IsNullOrEmpty(p) && request.QueryString[p] != null && !String.IsNullOrEmpty(request.QueryString[p])) .OrderBy(p => p).ToArray(); foreach (var paramname in paramnames) { keyBuilder.AppendFormat("qs{0}_{1}_", paramname.GetHashCode(), request.QueryString[paramname].GetHashCode()); } } var custom = GetVaryByCustomString(filterContext); if (!String.IsNullOrEmpty(custom)) { keyBuilder.AppendFormat("custom_{0}_", custom.GetHashCode()); } return(keyBuilder.ToString()); }
/// <summary> /// Creates the cache key. /// </summary> /// <param name="routeValues">The route values.</param> /// <returns>The cache key.</returns> private string CreateCacheKey(RouteValueDictionary routeValues, IDictionary <string, object> actionParameters) { // Create the cache key prefix as the controller and action method var sb = new StringBuilder(routeValues["controller"].ToString()); sb.Append("_").Append(routeValues["action"].ToString()); if (!string.IsNullOrWhiteSpace(VaryByParam)) { // Append the cache key from the vary by parameters object varyByParamObject = null; string[] varyByParamsSplit = null; bool gotValue = false; _lock.EnterReadLock(); try { gotValue = _varyByParamsSplitCache.TryGetValue(VaryByParam, out varyByParamsSplit); } finally { _lock.ExitReadLock(); } if (!gotValue) { _lock.EnterWriteLock(); try { varyByParamsSplit = VaryByParam.Split(",; ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); _varyByParamsSplitCache[VaryByParam] = varyByParamsSplit; } finally { _lock.ExitWriteLock(); } } foreach (var varyByParam in varyByParamsSplit) { // Skip invalid parameters if (!actionParameters.TryGetValue(varyByParam, out varyByParamObject)) { continue; } // Sometimes a parameter will be null if (varyByParamObject == null) { continue; } sb.Append("_").Append(varyByParamObject.ToString()); } } // Handle VaryByCustom if (!string.IsNullOrWhiteSpace(VaryByCustom)) { sb.Append("_" + HttpContext.Current.ApplicationInstance.GetVaryByCustomString(HttpContext.Current, VaryByCustom)); } // Handle VaryByHeader if (!string.IsNullOrWhiteSpace(VaryByHeader)) { sb.Append("_Header"); foreach (string Header in VaryByHeader.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) { try { string[] vals = HttpContext.Current.Request.Headers[Header] != null?HttpContext.Current.Request.Headers.GetValues(Header) : new string[] { }; sb.Append($"_{Header}={string.Join("|", vals)}"); } catch (Exception) { } } } if (!string.IsNullOrWhiteSpace(VaryByCookie)) { sb.Append("_Cookie"); foreach (string Cookie in VaryByCookie.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) { try { string val = HttpContext.Current.Request.Cookies[Cookie] != null ? HttpContext.Current.Request.Cookies[Cookie].Value : ""; sb.Append($"_{Cookie}={val}"); } catch (Exception) { } } } return(sb.ToString()); }