web-dev-qa-db-fra.com

Désactiver la mise en cache sur une vue partielle dans MVC 3

J'ai un problème avec une vue partielle mise en cache alors qu'elle ne devrait pas l'être. Cette vue partielle est utilisée pour afficher la connexion/déconnexion sur une page. Il utilise le code simple ci-dessous pour déterminer le lien à afficher. 

@if(Request.IsAuthenticated) {    
    <a href="@Url.Action("LogOff", "Account", new { area = "" })">Log Off</a> 
}
else {
    <a href="@Url.Action("LogOn", "Account", new { area = "" })">Log On</a>
}

Cette vue partielle est appelée avec toutes les pages de mon application MVC3, en utilisant 

@Html.Partial("_HeaderView")  

Dans la plupart de mes contrôleurs, le cache de sortie est défini, ce qui me permet de tirer parti de la mise en cache de mon contenu. 

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

Maintenant, le problème est que toute la page est mise en cache lorsque je ne souhaite pas que la vue partielle le soit. Cela provoque un comportement erroné où il affiche parfois LogOff même si l'utilisateur n'est pas connecté, etc. Y a-t-il un moyen de mettre en cache tout le contenu, sauf la vue partielle en question? 

20
SimpleUser

Ce que vous recherchez s'appelle Donut Caching. Voici un excellent article expliquant ce que c'est et comment le faire fonctionner http://www.devtrends.co.uk/blog/donut-output-caching-in-asp.net-mvc-3

9
torm

Vous pouvez désactiver la mise en cache en décorant le contrôleur qui affiche votre partiel _HeaderView avec les éléments suivants:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult HeaderView()
{
    return PartialView("_HeaderView");
}
18
Nick

Nous devrions définir le profil de cache dans le fichier Web.config au lieu de définir les valeurs de cache individuellement dans les pages pour éviter le code redondant. Nous pouvons faire référence au profil en utilisant la propriété CacheProfile de l'attribut OutputCache. Ce profil de cache sera appliqué à toutes les pages à moins que la page/méthode ne remplace ces paramètres.

<system.web>
  <caching>
    <outputCacheSettings>
      <outputCacheProfiles>
        <add name="CacheProfile" duration="60" varyByParam="*" />
      </outputCacheProfiles>
    </outputCacheSettings>
  </caching>
</system.web>

Et si vous souhaitez désactiver la mise en cache de votre action qui renvoie la vue partielle [_HeaderView], vous pouvez remplacer les paramètres du cache de configuration en décrivant cette méthode d'action spécifique, comme indiqué ci-dessous:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult RenderPartialView()
{
    return PartialView("_HeaderView");
}

J'espère que cela vous aiderait!

3
Swati Gupta

cela fonctionne pour moi .. 

 public ActionResult LogOff()
 {
     AuthenticationManager.SignOut();  
     var url = Url.Action("Index", "Web"); 
     HttpResponse.RemoveOutputCacheItem(url);           
     return RedirectToAction("Index", "Web");
 }
1
Miroslav

Il a fallu un peu de temps pour comprendre celui-ci après être rentré dans MVC. Il suffit de placer le paramètre Cache directement dans la vue En-tête partiel. Comme dans l'affichage du nom d'utilisateur. Pas besoin de code global ou côté serveur. Le seul problème est qu'une fois qu'une page est mise en cache, elle ne s'actualisera pas immédiatement après la connexion. Mais nous gardons la vitesse nécessaire lors de la navigation initiale pour les produits. Ok dans notre cas. 


 @if (Request.IsAuthenticated) 
 {
 @ * lorsque nous sommes authentifiés, ne cachez plus! * @ 
 HttpContext.Current.Response.Cache.SetCacheability (HttpCacheability.NoCache); 
 HttpContext.Current.Response.Cache.SetNoStore (); 
 HttpContext.Current.Response.Cache.SetNoServerCaching (); 
 @ * @ Html.Raw (DateTime.Now.ToString ()) * @ 
 @ Html.ActionLink ("Welcome" + (String.IsNullOrEmpty (((System.Security.Claims.ClaimsIdentity) User) Identity) .FindFirstValue ("UserName")? User.Identity.Name: ((System.Security.Claims) .ClaimsIdentity) User.Identity) .FindFirstValue ("UserName")), "Index", "Manage", routeValues: new {Area = "Store"}, htmlAttributes: new {title = "Manage"}) 
 } 
 autre
 {
 } 

0
Jeff