2012-08-05 9 views
6

Sto cercando di implementare un provider di cache di output combinato MongoDB/memoria da utilizzare con MVC4. Qui è la mia implementazione iniziale:Selezione del provider di cache di output personalizzato per azioni specifiche del controller

public class CustomOutputCacheProvider : OutputCacheProvider 
{ 
    public override object Get(string key) 
    { 
     FileLogger.Log(key); 
     return null; 
    } 

    public override object Add(string key, object entry, DateTime utcExpiry) 
    { 
     return entry; 
    } 

    public override void Set(string key, object entry, DateTime utcExpiry) 
    { 
    } 

    public override void Remove(string key) 
    { 
    } 
} 

E il mio ingresso Web di configurazione:

<caching> 
    <outputCache defaultProvider="CustomOutputCacheProvider"> 
    <providers> 
     <add name="CustomOutputCacheProvider" type="MyApp.Base.Mvc.CustomOutputCacheProvider" /> 
    </providers> 
    </outputCache> 
</caching> 

E l'utilizzo all'interno di HomeController:

[OutputCache(Duration = 15)] 
public ActionResult Index() 
{ 
    return Content("Home Page"); 
} 

Il mio problema è, quando si controlla il file di log per la chiavi richieste, vedo non solo la richiesta sul controller di casa, ma anche tutti gli altri percorsi:

a2/ <-- should only log this entry 
a2/test 
a2/images/test/50115c53/1f37e409/4c7ab27d/50115c531f37e4094c7ab27d.jpg 
a2/scripts/jquery-1.7.2.min.js 

Ho capito che non dovrei impostare CustomOutputCacheProvider come DefaultProvider in Web.Config, quello che non riuscivo a capire è come specificare il provider di cache che voglio usare per un'azione specifica del controller.

Con le pagine Web Asp.Net è possibile eseguirlo utilizzando <%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskCache" %> nella parte superiore della pagina, ma per MVC l'unica soluzione che è stato possibile trovare è sovrascrivere HttpApplication.GetOutputCacheProviderName Method in Global.asax.

Esiste un modo più elegante per eseguire ciò utilizzando l'attributo [OutputCache]?

+0

Aggiunto un altro suggerimento! – bUKaneer

+0

Interessante cosa è 'a2/test' e come si adatta alla richiesta originale' a2/'? –

+0

Nessuna idea, quello che richiedo è 'http: // host/test'. Mvc aggiunge a2 (vedere [OutputCacheAttribute.cs] (http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/98d041ae352f#src%2fSystem.Web.Mvc%2fOutputCacheAttribute.cs)) durante la generazione della chiave –

risposta

5

C'è un modo più elegante per impostare l'OutputCacheProvider utilizzando il [OutputCache] attributo?

Penso che la risposta è no, (anche non con il rilascio mvc4 corrente) poiché non v'è alcuna relazione tra l'attuazione di un personalizzato OutputCacheProvider e decorando un'azione con l'attributo OutputCache.

Come avete scoperto implementando il provider personalizzato e la registrazione nel metodo Get, viene visualizzata ogni richiesta effettuata sul server Web. Se dovessi rimuovere l'attributo OutputCache da tutte le tue azioni, vedrai comunque tutte le richieste nel file di log esterno. Ho pensato che la risposta per questo ASP.NET MVC hits outputcache for every action fosse abbastanza utile per confermarlo.

Poiché sembra che si desidera solo per implementare un provider di uscita-cache, allora penso che l'unica opzione è quella di non impostare il provider di default e continuare ad ignorare l'attuazione GetOutputCacheProviderName (come si è già accennato).Forse qualcosa di simile per escludere tutti Content, Immagini e script

public override string GetOutputCacheProviderName(HttpContext context) 
{ 
    string absolutePath = context.Request.Url.AbsolutePath; 

    if (absolutePath.StartsWith("/Content/", StringComparison.CurrentCultureIgnoreCase) 
     || absolutePath.StartsWith("/Scripts/", StringComparison.CurrentCultureIgnoreCase) 
     || absolutePath.StartsWith("/Images/", StringComparison.CurrentCultureIgnoreCase)) 
     return base.GetOutputCacheProviderName(context); 

    return "CustomOutputCacheProvider"; 
} 

Se è necessario implementare più di un fornitore di output-cache allora credo si dovrà implementare un assistente per dare tu il nome del fornitore corretto. Ma ecco un esempio in cui ho risolto i dati di routing per te; dove come l'esempio precedente guardava direttamente l'url.

public override string GetOutputCacheProviderName(HttpContext context) 
{  
    RouteCollection rc = new RouteCollection(); 
    MvcApplication.RegisterRoutes(rc); 
    RouteData rd = rc.GetRouteData(new HttpContextWrapper(HttpContext.Current)); 

    if (rd == null) 
     return base.GetOutputCacheProviderName(context); 

    var controller = rd.Values["controller"].ToString(); 
    var action = rd.Values["action"].ToString(); 

    if (controller.Equals("Content", StringComparison.CurrentCultureIgnoreCase) 
     || controller.Equals("Scripts", StringComparison.CurrentCultureIgnoreCase) 
     || controller.Equals("Images", StringComparison.CurrentCultureIgnoreCase)) 
     return base.GetOutputCacheProviderName(context); 

    if (controller.Equals("Account", StringComparison.CurrentCultureIgnoreCase)) 
     return "AccountOutputCacheProvider"; 
    if (controller.Equals("Something", StringComparison.CurrentCultureIgnoreCase)) 
     return controller + "OutputCacheProvider"; 

    return "CustomOutputCacheProvider"; 
} 
+0

Non è la risposta che stavo cercando, ma il collegamento ha aiutato. Sembra che dovrò implementare la mia soluzione. –

1

Se io dovessi, proverei a scrivere MyOutputCachAttribute ereditato da OutputCachAttribute che sceglierà il fornitore in base al suo parametro.

+0

L'ho preso in considerazione, ma sembra quasi uguale il lavoro per implementare il mio meccanismo di caching. Vedi [OutputCacheAttribute.cs] (http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/98d041ae352f#src%2fSystem.Web.Mvc%2fOutputCacheAttribute.cs) –

0

Controllare questo articolo di MSDN Magazine (con il codice sorgente e gli esempi riferimento MongoDB & Azure come fornitori di cache distribuita) potrebbe fornire qualche informazione http://msdn.microsoft.com/en-us/magazine/gg650661.aspx

EDIT

si può utilizzare l'impostazione del CacheProfile per specificare il fornitore come suggerito qui?

http://www.dotnetcurry.com/ShowArticle.aspx?ID=665

+0

Grazie, già visto, ha lo stesso problema. –

+0

Sfortunatamente, CacheProfile non ha l'impostazione del provider impostata. –

Problemi correlati