OutputCache因使用ModelBinder从Session传递的复杂对象属性而变化

时间:2016-12-30 17:28:45

标签: asp.net-mvc-4 asp.net-caching

我们在会话和OutputCache中使用Couchbase。

在这种情况下,我们如何使用从Session中检索值的自定义模型绑定器传递给方法的复杂对象进行缓存?

这是我想用OutputCache属性缓存的方法的签名:

[HttpGet]
[OutputCache(CacheProfile = "MyObjectsCache", VaryByParam = "myParam")]
public ActionResult Index([ModelBinder(typeof (CustomVariableSessionModelBinder<MyClass>))] MyClass myParam)
{

注意:此处使用ModelBinder的原因超出了我的范围,我无法更改。

MyClass是一个具有Id的复杂对象。我想使用Id作为缓存标识符。

public class MyClass
{
   public int Id{get;set;}
   //Other Properties

这是从Session中检索对象的方式:

var sessionKey = typeof (MyNamespace.MyClass).FullName;
var httpContext = HttpContext.Current;
MyNamespace.MyClass newObject = null;

if (httpContext.Session != null)
{
    newObject = httpContext.Session[sessionKey] as MyNamespace.MyClass;
}

是否可以在此方案中使用VaryByParam,还是必须使用VaryByCustom

1 个答案:

答案 0 :(得分:1)

我还没有对此进行测试,但 应该工作。不过,它无论如何都是你唯一的选择。

除了内置的变化方式外,您还可以通过&#34; Custom&#34;来改变。这将调用Global.asax中的方法,您需要覆盖:GetVaryByCustomString。对于您的情况重要的是,此方法已通过HttpContext,因此您应该能够查看会话。从本质上讲,解决方案看起来像:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    var args = custom.ToLower().Split(';');
    var sb = new StringBuilder();

    foreach (var arg in args)
    {
        switch (arg)
        {
            case "session":
                var obj = // get your object from session
                // now create some unique string to append
                sb.AppendFormat("Session{0}", obj.Id);
        }
    }

    return sb.ToString();
}

这是为了处理多种不同类型的&#34; custom&#34;各种类型。例如,如果您想要改变&#34; User&#34;这是常见的,您只需在交换机中为其添加一个案例。重要的是,此方法返回的字符串实际上是输出缓存的变化,因此您希望它对于该情况是唯一的。这就是为什么我将对象的id加上&#34; Session&#34;这里。例如,如果您刚刚添加了ID,请说出123,然后在另一个场景中,您会因用户而异,并且该字符串仅由用户的ID组成,这恰好是123也是如此。它与输出缓存的字符串相同,并且您会以一些奇怪的结果结束。请注意自定义字符串的外观。

现在,您只需更改OutputCache属性,例如:

[OutputCache(CacheProfile = "MyObjectsCache", VaryByParam = "myParam", VaryByCustom = "Session")]

注意:要一次改变多个自定义内容,您可以使用;(基于上述代码的工作方式)将它们分开。例如:VaryByCustom = "Session;User"