/// <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()); }
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; } } }
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); }