如果你只是想缓存数据,那么
OutputCache
不是正确的机制。
OutputCache
可用于缓存操作方法生成的HTML,以便无需重新生成。如果要缓存数据,可以使用
HttpContextBase.Cache
轻松实现。
此外,我
建议不要使用基控制器类。这肯定意味着您将把
feature a、
feature b和
feature c的逻辑混合在同一个基础控制器中-您正在创建一个
God对象。MVC有更好的方法-
过滤器,它们可以注册为所有操作运行并且可与过滤器一起使用在特定操作上。
虽然可能没有任何理由将全局过滤器用于缓存,因为通常数据是在请求点被缓存的,但我已经创建了一个演示如何完成它的演示。请注意,缓存是一个非常广泛的主题,可以通过多种方式来完成,但是因为您没有提供任何关于正在缓存什么、数据源是什么或如何使用它的信息,所以我只展示这个可能的方法。
MyCacheFilter
在这里我们有一个操作过滤器执行缓存。由于操作过滤器保证在视图之前运行,因此可以通过这种方式实现。
MyCacheFilter
执行3件事情:
- 从缓存中读取数据
- 检查数据是否存在,如果不存在,则重新加载缓存
- 将对数据对象的引用添加到请求缓存中,在应用程序中的任何其他位置(包括视图)中都可以访问它。
public class MyCacheFilter : IActionFilter
{
private static string MY_DEFAULTS_CACHE_KEY = "MY_DEFAULTS";
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var cache = filterContext.HttpContext.Cache;
IDictionary<string, string> defaults =
cache[MY_DEFAULTS_CACHE_KEY] as IDictionary<string, string>;
if (defaults == null)
{
defaults = GetDefaults();
cache.Insert(
MY_DEFAULTS_CACHE_KEY,
defaults,
null,
DateTime.Now.AddHours(1),
System.Web.Caching.Cache.NoSlidingExpiration);
}
filterContext.HttpContext.SetMyDefaults(defaults);
}
private IDictionary<string, string> GetDefaults()
{
var defaults = new Dictionary<string, string>
{
{ "value1", "testing" },
{ "value2", "hello world" },
{ "value3", "this works" }
};
return new System.Collections.ObjectModel.ReadOnlyDictionary<string, string>(defaults);
}
}
使用MyCacheFilter
为了使用我们的缓存过滤器并确保在显示任何视图之前填充缓存,我们将其注册为全局过滤器。全局过滤器非常适用于将不同功能模块化到不同的类中,这样它们就可以很容易地维护(不像基础控制器)。
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new MyCacheFilter());
filters.Add(new HandleErrorAttribute());
}
}
HttpContextBaseExtensions
为了使缓存数据对应用程序更加类型安全,这里提供了几个实用的扩展方法。
public static class HttpContextBaseExtensions
{
internal static string MY_DEFAULTS_KEY = "MY_DEFAULTS";
public static string GetMyDefault(this HttpContextBase context, string defaultKey)
{
IDictionary<string, string> defaults = context.Items[MY_DEFAULTS_KEY] as IDictionary<string, string>;
string result = null;
defaults.TryGetValue(defaultKey, out result);
return result ?? String.Empty;
}
internal static void SetMyDefaults(this HttpContextBase context, IDictionary<string, string> defaults)
{
context.Items[MY_DEFAULTS_KEY] = defaults;
}
}
用法
最后,我们需要使用视图中的数据。由于HttpContextBase
对象上有扩展方法,所以我们只需要通过视图访问它并调用我们的扩展方法即可。
<p>
value1: @this.Context.GetMyDefault("value1")<br />
value2: @this.Context.GetMyDefault("value2")<br />
value3: @this.Context.GetMyDefault("value3")<br />
</p>
我已经在这个GitHub存储库中创建了一个可工作的演示解决方案:
点击此处。
再次强调,这不是唯一的方法。您可能希望根据您的应用程序进行一些修改。例如,您可以使用
ViewData
将数据返回到视图,而不是使用
HttpContextBase.Items
。或者,您可能希望摆脱全局过滤器,并将缓存模式移到单个扩展方法中,从缓存中加载/返回数据。确切的解决方案取决于您在问题中未提供的要求。
HttpContext.Cache
或System.Runtime.Caching.MemoryCache
。 - NightOwl888