internal string GetChildActionUniqueId(ActionExecutingContext filterContext)
        {
            var uniqueIdBuilder = new StringBuilder();

            // Start with a prefix, presuming that we share the cache with other users
            uniqueIdBuilder.Append(CacheKeyPrefix);

            // Unique ID of the action description
            uniqueIdBuilder.Append(filterContext.ActionDescriptor.UniqueId);

            // Unique ID from the VaryByCustom settings, if any
            uniqueIdBuilder.Append(MyDescriptorUtil.CreateUniqueId(VaryByCustom));
            if (!String.IsNullOrEmpty(VaryByCustom))
            {
                string varyByCustomResult = filterContext.HttpContext.ApplicationInstance.GetVaryByCustomString(HttpContext.Current, VaryByCustom);
                uniqueIdBuilder.Append(varyByCustomResult);
            }

            // Unique ID from the VaryByParam settings, if any
            uniqueIdBuilder.Append(GetUniqueIdFromActionParameters(filterContext, SplitVaryByParam(VaryByParam)));

            // The key is typically too long to be useful, so we use a cryptographic hash
            // as the actual key (better randomization and key distribution, so small vary
            // values will generate dramatically different keys).
            using (SHA256 sha = SHA256.Create())
            {
                return(Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(uniqueIdBuilder.ToString()))));
            }
        }
        private static string GetUniqueIdFromActionParameters(ActionExecutingContext filterContext, IEnumerable <string> keys)
        {
            // Generate a unique ID of normalized key names + key values
            var keyValues = new Dictionary <string, object>(filterContext.ActionParameters, StringComparer.OrdinalIgnoreCase);

            keys = (keys ?? keyValues.Keys).Select(key => key.ToUpperInvariant())
                   .OrderBy(key => key, StringComparer.Ordinal);

            return(MyDescriptorUtil.CreateUniqueId(keys.Concat(keys.Select(key => keyValues.ContainsKey(key) ? keyValues[key] : null))));
        }