2013-03-04 6 views

risposta

6

se si dispone di un modello come

public class person{ 
public string Name {get;set;} 
public string location {get;set;} 
} 

e nel (fortemente tipizzato) visualizzare si dispone di un modulo

@model Person 

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

e si invia il modulo a un ActionResult savePerson, con diversi firma come

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

} 

o

public ActionResult savePerson(string Name, string location){ 

} 

quindi penso che se si annotare l'ActionResult come

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

lo farà per voi, o se si dispone di un modello complesso come

public class person{ 
public string Name {get;set;} 
public Location loc {get;set;} 
} 
public class Location{ 
    public string address 
} 

provare

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

Ho avuto lo stesso requisito di cui sopra e ho trovato un approccio leggermente diverso

La classe

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

attributo di utilizzo

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

con questo nuovo un ttribute, è possibile specificare quale tipo [s] utilizzare per la memorizzazione nella cache e la chiave di cache verrà calcolata in base ai valori di ciascuna delle sue proprietà.

+0

Qual è il tuo metodo _types.AtLeastOnce() ?? – leen3o

+0

@ leen3o Il metodo 'AtLeastOnce (Expression)' è solo un metodo di estensione Enumerable equivalente al LINQ 'Any (Expression)' –

-1

per oggetto, solo che funzionano bene:

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