Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            var acDomain = filterContext.HttpContext.Application[Constants.ApplicationRuntime.AcDomainCacheKey] as IAcDomain;

            if (Enable || acDomain.Config.EnableClientCache)
            {
                if (Duration <= 0)
                {
                    return;
                }

                HttpCachePolicyBase cache         = filterContext.HttpContext.Response.Cache;
                TimeSpan            cacheDuration = TimeSpan.FromSeconds(Duration);

                cache.SetCacheability(HttpCacheability.Public);
                cache.SetExpires(DateTime.Now.Add(cacheDuration));
                if (!string.IsNullOrEmpty(VaryByParam))
                {
                    string[] parms = VaryByParam.Split(';');
                    foreach (var parm in parms)
                    {
                        cache.VaryByParams[parm] = true;
                    }
                }
                cache.SetMaxAge(cacheDuration);
                cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
            }
        }
        string GetCacheKey(HttpActionContext actionContext)
        {
            StringBuilder sb = new StringBuilder("b1", actionContext.Request.RequestUri.AbsolutePath.Length + 2);

            sb.Append(actionContext.Request.RequestUri.AbsolutePath.ToLower());

            if (!"none".Equals(VaryByParam, StringComparison.OrdinalIgnoreCase))
            {
                NameValueCollection querys = actionContext.Request.RequestUri.ParseQueryString();
                if ("*".Equals(VaryByParam) || string.IsNullOrEmpty(VaryByParam))
                {
                    foreach (var item in querys.AllKeys)
                    {
                        sb.Append(item.ToLower());
                        sb.Append(querys[item]);
                    }
                }
                else
                {
                    var keys = VaryByParam.Split(';');
                    foreach (var item in keys)
                    {
                        if (querys.AllKeys.Contains(item, StringComparer.OrdinalIgnoreCase))
                        {
                            sb.Append(item.ToLower());
                            sb.Append(querys[item]);
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(VaryByCustom))
            {
                var customs = VaryByParam.Split(';');

                foreach (var item in customs)
                {
                    if (ApiOutputCacheConfig.GlobalVaryByCustomFunc != null)
                    {
                        sb.Append(item.ToLower());
                        sb.Append(ApiOutputCacheConfig.GlobalVaryByCustomFunc(actionContext.Request, item));
                    }
                    else
                    {
                        throw new Exception("要使用VaryByCustom,必须先定义VaryByCustomFunc或GlobalVaryByCustomFunc");
                    }
                }
            }

            if (VaryByMediaType)
            {
                var negotiator      = actionContext.Request.GetConfiguration().Services.GetContentNegotiator();
                var negotiateResult = negotiator.Negotiate(actionContext.ActionDescriptor.ReturnType, actionContext.Request, actionContext.Request.GetConfiguration().Formatters);
                sb.Append(negotiateResult.MediaType);
            }
            return(sb.ToString());
        }
Пример #3
0
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (VaryByParam.IsNullOrEmpty())
            {
                VaryByParam = "none";                                                 // see http://stackoverflow.com/questions/288608/asp-net-mvc-output-caching-the-directive-or-the-configuration-settings-profile-m
            }
            VaryByParam = VaryByParam.Replace(",", ";");                              //proper delimiter

            this.Location = System.Web.UI.OutputCacheLocation.Client;                 // to make sure people only get their own cached stuff
            Current.Context.Response.Cache.SetCacheability(HttpCacheability.Private); // same thing, just in case

            if (filterContext.IsChildAction)
            {
                return; // don't cache child actions - see http://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx "Cooperating with Output Caching"
            }

            if (AllowOnlyValidSearchEngines)
            {
                var IsSearchEngine = (filterContext.Controller as valentines.Controllers.CustomControllerBase).IsSearchEngineDns();
                if (IsSearchEngine)
                {
                    base.OnResultExecuting(filterContext);
                    return;
                }
                return;
            }
            else
            {
                if (NoCachingForAuthenticatedUsers)
                {
                    if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
                    {
                        base.OnResultExecuting(filterContext);
                    }
                    return;
                }
                else
                {
                    base.OnResultExecuting(filterContext);
                    return;
                }
            }
        }
Пример #4
0
        private string CreateCacheKey(RouteValueDictionary routeValues,
                                      IDictionary <string, object> actionParameters)
        {
            var sb = new StringBuilder(routeValues["controller"].ToString());

            sb.Append("_").Append(routeValues["action"].ToString());

            if (string.IsNullOrWhiteSpace(VaryByParam))
            {
                return(sb.ToString());
            }

            if (VaryByParam == "*")
            {
                foreach (var p in actionParameters)
                {
                    sb.Append("_");
                    sb.Append(GetObjectValue(p.Value));
                }
                return(sb.ToString());
            }

            if (!VaryByParamsSplitCache.TryGetValue(VaryByParam, out var varyByParamsSplit))
            {
                varyByParamsSplit = VaryByParam.Split(new[] { ',', ' ' },
                                                      StringSplitOptions.RemoveEmptyEntries);
                VaryByParamsSplitCache[VaryByParam] = varyByParamsSplit;
            }

            foreach (var varyByParam in varyByParamsSplit)
            {
                if (!actionParameters.TryGetValue(varyByParam, out object varyByParamObject))
                {
                    continue;
                }
                sb.Append("_");
                sb.Append(GetObjectValue(varyByParamObject));
            }

            return(sb.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());
        }
        /// <summary>
        /// Retrieves the cache key based on the current property values.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="control"></param>
        /// <param name="container"></param>
        /// <param name="getDefaultKey"></param>
        /// <returns></returns>
        public string GetCacheKey(System.Web.HttpContext context, System.Web.UI.Control control, object container, Converter <string, string> getDefaultKey)
        {
            string cacheKey = KeyFormat;

            if (Parameters != null && Parameters.Count > 0)
            {
                // use the parameters collection to build the dependency
                IOrderedDictionary values = Parameters.GetValues(context, control);

                if (container != null)
                {
                    // process CacheItemParameter objects, lookup the value based on the container
                    foreach (Parameter param in Parameters)
                    {
                        if (param is CacheItemParameter)
                        {
                            string format       = (param as CacheItemParameter).Format;
                            string propertyName = (param as CacheItemParameter).PropertyName;
                            string result       = DataBinder.Eval(container, propertyName, format);

                            if (!string.IsNullOrEmpty(result))
                            {
                                values[param.Name] = result;
                            }
                        }
                    }
                }

                if (!string.IsNullOrEmpty(KeyFormat))
                {
                    foreach (DictionaryEntry entry in values)
                    {
                        if (entry.Key != null)
                        {
                            string key = entry.Key.ToString().Trim();

                            if (!key.StartsWith("@"))
                            {
                                key = "@" + key;
                            }

                            cacheKey = Regex.Replace(cacheKey, key, "{0}".FormatWith(entry.Value), RegexOptions.IgnoreCase);
                        }
                    }
                }
            }
            else if (!string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(PropertyName))
            {
                string result = null;

                if (container != null)
                {
                    try
                    {
                        result = DataBinder.Eval(container, PropertyName, "{0}");
                    }
                    catch (Exception e)
                    {
                        Tracing.FrameworkError("CacheKeyDependency", "GetCacheKey", "Invalid cache parameter settings.");
                        Tracing.FrameworkError("CacheKeyDependency", "GetCacheKey", e.ToString());
                    }
                }

                // use this object to build the dependency
                string key = Name.Trim();

                if (!key.StartsWith("@"))
                {
                    key = "@" + key;
                }

                cacheKey = Regex.Replace(cacheKey, key, result ?? string.Empty, RegexOptions.IgnoreCase);
            }

            if (string.IsNullOrEmpty(cacheKey))
            {
                // could not find a suitable cacheKey from the parameters, build a default key
                cacheKey = "Adxstudio:{0}:ID={1}".FormatWith(control.GetType().FullName, control.ID);

                // provide an opportunity to override this suggested default
                if (getDefaultKey != null)
                {
                    cacheKey = getDefaultKey(cacheKey);
                }
            }

            if (VaryByUser)
            {
                IIdentity identity;

                if (TryGetCurrentIdentity(out identity) && identity.IsAuthenticated)
                {
                    cacheKey += ":Identity={0}".FormatWith(identity.Name);
                }
            }

            if (!string.IsNullOrEmpty(VaryByParam))
            {
                foreach (string section in VaryByParam.Split(_varySeparator))
                {
                    string param = section.Trim();
                    cacheKey += ":{0}={1}".FormatWith(param, context.Request[param]);
                }
            }

            return(cacheKey);
        }