OutputCache因复杂的对象属性而异

时间:2013-03-04 01:56:50

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

我有一个控制器动作接收一个复杂的对象作为参数,我需要OutputCache来改变这个复杂对象的一个​​属性。这可能吗?怎么样?

3 个答案:

答案 0 :(得分:6)

如果您有类似

的模型
public class person{
 public string Name {get;set;}
 public string location {get;set;}
} 

并在(强类型)视图中有一个表单

 @model Person

 @Html.BeginForm(){
  @Html.TextBoxFor(x=>x.Name)
  @Html.TextBoxFor(x=>x.location)
 }

并将表单提交给ActionResult savePerson,其中包含不同的签名,例如

public ActionResult savePerson(Person p){
 // p.Name
 // p.location

}

public ActionResult savePerson(string Name, string location){

}

因此我认为如果你注释ActionResult就像

那样
[OutputCache(Duration=3600, VaryByParam="Name")]
public ActionResult savePerson(Person p)
{
    //
    return View();
}

它会为你做,或者你有一个像

这样的复杂模型
public class person{
 public string Name {get;set;}
 public Location loc {get;set;}
} 
public class Location{
  public string address
}

尝试

[OutputCache(Duration=3600, VaryByParam="Person.Location.address")]
public ActionResult savePerson(Person p)
{
    //
    return View();
}

答案 1 :(得分:4)

我有与上述相同的要求,并提出了稍微不同的方法

课程

/// <summary>
/// This class is used to encapsulate search filters for monitor graphs
/// </summary>
public class DatacarMonitorSearchCriteriaModel
{
    public int? SynergyCode { get; set; }

    [Required]
    [DataType(DataType.Date)]
    public DateTime StartDate { get; set; }

    [Required]
    [DataType(DataType.Date)]
    public DateTime EndDate { get; set; }

    /// <summary>
    /// Filter to apply 
    /// </summary>
    public IEnumerable<int> Countries { get; set; }


    public DatacarMonitorSearchCriteriaModel()
    {
        Countries = new List<int>();
    }



}

<强> OutputCacheComplexAttribute

/// <summary>
/// <para>
///     An instance of this class mimic the behaviour of OutputCacheAttribute but for complex objects.
/// </para>
/// <para>
///     It allows to cache the output of any action that takes complex objects 
/// </para>
/// </summary>
public class OutputCacheComplexAttribute : OutputCacheAttribute
{
    private readonly Type[] _types;

    private string _cachedKey;

    /// <summary>
    /// Initializes a new instance of the <see cref="OutputCacheComplexAttribute"/> class.
    /// </summary>
    /// <param name="types">Types that this attribute will lookup for in QueryString/Form data and store values in cache.</param>
    /// <exception cref="System.ArgumentOutOfRangeException">type;type cannot be null</exception>
    public OutputCacheComplexAttribute(params Type[] types)
    {
        if (types == null)
        {
            throw new ArgumentOutOfRangeException("type", "type cannot be null");
        }
        _types = types;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        StringBuilder sbCachedKey = new StringBuilder();
        if (filterContext.HttpContext.Request.Url != null)
        {
            string path = filterContext.HttpContext.Request.Url.PathAndQuery;
            IDictionary<string, object> parameters = filterContext.ActionParameters;

            //we need to compute a cache key which will be used to store the action output for later retrieval
            //The cache key scheme is 
            //    {url}:{key 1}:{value};[{key 2}:{value 2}[; ... {key n}:{value n}]];  
            // where : 
            //  - url is the url of the action that will be executed
            //  - key n is the name of the n-th parameter
            //  - value n is the value of the n-th parameter as json string.
            foreach (KeyValuePair<string, object> kv in parameters)
            {
                var kv1 = kv;
                if (kv.Value != null && _types.AtLeastOnce(t => t.IsInstanceOfType(kv1.Value)))
                {
                    sbCachedKey = sbCachedKey.AppendFormat("{0}:{1};",kv.Key,
                        JsonConvert.SerializeObject(kv.Value, Formatting.None, new JsonSerializerSettings()
                        {
                            NullValueHandling = NullValueHandling.Ignore,
                            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                        }));
                }
            }

            _cachedKey = String.Format("{0}:{1}:{2}", GetType().Name, path, sbCachedKey.ToString());
        }


        if (!String.IsNullOrWhiteSpace(_cachedKey) && filterContext.HttpContext.Cache[_cachedKey] != null)
        {
            filterContext.Result = (ActionResult)filterContext.HttpContext.Cache[_cachedKey];
        }
        else
        {
            base.OnActionExecuting(filterContext);
        }
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (!String.IsNullOrWhiteSpace(_cachedKey))
        {
            filterContext.HttpContext.Cache.Add(_cachedKey, filterContext.Result, null,
                DateTime.UtcNow.AddSeconds(Duration), Cache.NoSlidingExpiration,
                CacheItemPriority.Default, null);
        }

        base.OnActionExecuted(filterContext);
    }
}

属性用法

[OutputCacheComplex(typeof(DatacarMonitorSearchCriteriaModel), Duration = OutputCacheDurationInSeconds, Location = OutputCacheLocation.Server)]
public async Task<JsonNetResult<DatacarMonitorDetailModel>> ReadMonitorDetailsJson([DataSourceRequest] DataSourceRequest request, DatacarMonitorSearchCriteriaModel criteria)
{ 
     //some really complicated code here
}

使用这个新属性,您可以指定用于缓存的类型[s],并根据每个属性的值计算缓存键。

答案 2 :(得分:-1)

对于对象,只是工作正常:

    [OutputCache(VaryByParam = "*", Duration = 60)]