2012-08-05 10 views
6

Próbuję zaimplementować dostawcę pamięci podręcznej wyjścia MongoDB/Memory w celu użycia z MVC4. Oto moja pierwsza realizacja:Wybieranie niestandardowego dostawcy bufora wyjściowego dla określonych działań kontrolera

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) 
    { 
    } 
} 

A mój wpis web config:

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

A Wykorzystanie w ciągu HomeController:

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

Moim problemem jest to, kiedy sprawdzić logi dla żądane klucze, widzę nie tylko żądanie do kontrolera macierzystego, ale wszystkie inne ścieżki również:

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

Doszedłem do wniosku, że nie powinienem ustawić CustomOutputCacheProvider jako defaultProvider w Web.Config, czego nie mogłem wymyślić, jak określić dostawcę pamięci podręcznej, który chcę użyć dla określonego działania kontrolera.

Dzięki stronom internetowym Asp.Net można to zrobić, korzystając z <%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskCache" %> u góry strony, ale dla MVC jedynym rozwiązaniem, jakie mogę znaleźć, jest przesłonięcie HttpApplication.GetOutputCacheProviderName Method w pliku Global.asax.

Czy istnieje bardziej elegancki sposób osiągnięcia tego poprzez użycie atrybutu [OutputCache]?

+0

Dodano kolejną sugestię! – bUKaneer

+0

Ciekawe, co to jest "a2/test" i jak pasuje do oryginalnego żądania 'a2 /'? –

+0

Nie mam pojęcia, proszę o "http: // host/test". Mvc dodaje a2 (zobacz [OutputCacheAttribute.cs] (http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/98d041ae352f#src%2fSystem.Web.Mvc%2fOutputCacheAttribute.cs)) podczas generowania klucza –

Odpowiedz

5

Czy jest bardziej elegancki sposób ustawić OutputCacheProvider używając [OutputCache] atrybut?

Myślę, że odpowiedź brzmi nie, (no nie z obecnym wydaniu mvc4), ponieważ nie ma żadnego związku między wdrożenie niestandardowych OutputCacheProvider wykończeniowe działanie z atrybutem OutputCache.

Jak odkryłeś za pomocą niestandardowego dostawcy i logowanie w metodzie Get możesz zobaczyć każde żądanie wykonane na serwerze sieciowym. Jeśli usuniesz atrybut OutputCache ze wszystkich swoich akcji, nadal będziesz widzieć każde żądanie w pliku dziennika zewnętrznego. Myślałem, że odpowiedź na to ASP.NET MVC hits outputcache for every action była bardzo przydatna, aby to potwierdzić.

Ponieważ wygląda na to, tylko chcą wprowadzić jeden dostawca wyjście-cache to myślę, że jedynym rozwiązaniem jest nie ustawić domyślnego dostawcy i nadal zastąpić realizację GetOutputCacheProviderName (jak już wspomniano).Być może coś w tym, aby wykluczyć wszelkie zawartość, Obrazy i Skrypty

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"; 
} 

Jeśli trzeba zaimplementować więcej niż jednego dostawcy wyjście-cache to chyba trzeba będzie wdrożyć pomocnika dać masz poprawną nazwę dostawcy. Ale oto przykład, w którym rozwiązałem dla Ciebie dane dotyczące routingu; gdzie jako poprzedni przykład wyglądał bezpośrednio pod adresem 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

Nie odpowiedź, której szukałem, ale link pomógł. Wygląda na to, że będę musiał wdrożyć własne rozwiązanie. –

1

Jeśli i gdzie, spróbuję napisać MyOutputCachAttribute odziedziczony z OutputCachAttribute, który wybierze dostawcę według jego parametru.

+0

Rozważałem to, ale wydaje się, że prawie taka sama praca polega na implementacji mojego własnego mechanizmu buforowania. Zobacz [OutputCacheAttribute.cs] (http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/98d041ae352f#src%2fSystem.Web.Mvc%2fOutputCacheAttribute.cs) –

0

Sprawdź ten artykuł z MSDN Magazine (z kodem źródłowym i przykłady odwołującego MongoDB & Azure jako rozproszonych dostawców cache) może również zapewnić wgląd http://msdn.microsoft.com/en-us/magazine/gg650661.aspx

EDIT

można użyć CacheProfile ustawienie, aby określić usługodawca, jak sugerowano tutaj?

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

+0

Dzięki temu, już widziałem, ma ten sam problem. –

+0

Niestety, CacheProfile nie ma ustawionego ustawienia dostawcy. –

Powiązane problemy