2017-06-26 3 views
0

J'ai configuré CustomCache pour mon site Web. Tout fonctionne comme prévu, je peux voir le dossier cache avec les fichiers binaires. Quand je visite le site, je reçois les pages mises en cache et il rend comme il se doit. Le problème est que lorsque j'essaie d'utiliser les outils Google pour les webmasters pour afficher la page, Google ne peut pas accéder au chemin css généré généré dans BundleConfig ~/bundles/styles/maincss/, il en va de même pour le chemin javascript.`. Lorsque je visite ces deux chemins, je peux voir les fichiers JS et CSS minifiés et le navigateur rend la page correctement. Cela pose un problème, car lorsque je teste la page à l'aide de l'outil de test mobile, les pages ne sont pas adaptées aux mobiles. Pour une raison quelconque, Google ne peut pas accéder à ces chemins, bien que lorsque je cours l'exploration du Web dans les outils pour les webmasters, cela rende un bon résultat pour l'utilisateur, mais pas pour Google-bot.Google ne peut pas explorer les chemins CSS et JS générés à partir de la sortie personnalisée

Cela a fonctionné lorsque je n'utilise pas la mise en cache de sortie personnalisée, uniquement la sortie par défaut.

Une idée pour résoudre ce problème.

code personnalisé OutputCache:

Web.config:

</connectionStrings> 
<appSettings> 
    <add key="CacheLocation" value="~/Cache"/> 
</appSettings> 
<system.web> 
    <caching> 
    <outputCache defaultProvider="FileCache"> 
     <providers> 
     <add name="FileCache" type="ProjectX.FileCacheProvider"/> 
    </providers> 
    </outputCache> 
</caching> 

Classe caching:

using System; 
using System.Configuration; 
using System.IO; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.Web; 
using System.Web.Caching; 

namespace ProjectX 
{ 
    [Serializable] 
    public class CacheItem 
    { 
     public object Item { get; set; } 
     public DateTime Expiry { get; set; } 
    } 

    public class FileCacheProvider : OutputCacheProvider 
    { 
     private string CacheLocation 
     { 
      get 
      { 
       string strCacheLocation = ConfigurationManager.AppSettings["CacheLocation"]; 
       strCacheLocation = HttpContext.Current.Server.MapPath(strCacheLocation); 
       return strCacheLocation + @"\"; 
      } 
     } 


     private string GetFullPathForKey(string key) 
     { 
      string temp = key.Replace('/', '$'); 
      return CacheLocation + temp; 
     } 

     public override object Add(string key, object entry, DateTime utcExpiry) 
     { 
      object obj = this.Get(key); 
      if (obj != null) 
      { 
       return obj; 
      } 
      else 
      { 
       this.Set(key, entry, utcExpiry); 
       return entry; 
      } 
     } 

     public override void Remove(string key) 
     { 
      string filePath = GetFullPathForKey(key); 
      if (File.Exists(filePath)) 
      { 
       File.Delete(filePath); 
      } 
     } 

     public override object Get(string key) 
     { 
      string filePath = GetFullPathForKey(key); 
      if (!File.Exists(filePath)) 
      { 
       return null; 
      } 
      CacheItem item = null; 
      FileStream fileStream = File.OpenRead(filePath); 
      BinaryFormatter formatter = new BinaryFormatter(); 
      item = (CacheItem)formatter.Deserialize(fileStream); 
      fileStream.Close(); 
      if (item == null || item.Expiry <= DateTime.UtcNow) 
      { 
       Remove(key); 
       return null; 
      } 
      return item.Item; 
     } 



     public override void Set(string key, object entry, DateTime utcExpiry) 
     { 
      string filePath = GetFullPathForKey(key); 
      CacheItem item = new CacheItem { Expiry = utcExpiry, Item = entry }; 
      FileStream fileStream = File.OpenWrite(filePath); 
      BinaryFormatter formatter = new BinaryFormatter(); 
      formatter.Serialize(fileStream, item); 
      fileStream.Close(); 
     } 
    } 
} 
+0

@mjwills J'ai mis à jour la question avec le code. –

+0

Si vous mettez un 'Thread.Sleep (5000)' avant et après 'FileStream fileStream = File.OpenWrite (filePath);' vider le cache de votre navigateur, redémarrez IIS et ensuite charger la même ressource JS dans deux navigateurs distincts (disons Chrome et Firefox) en même temps obtenez-vous une erreur parce que deux choses essaient d'écrire dans le fichier en même temps? – mjwills

+0

@mjwills Je ne reçois pas d'erreur, Google ne peut pas y accéder. J'ai initié une exploration dans les outils webmaster plusieurs fois et il n'était toujours pas capable d'y accéder. Je suis capable avec mon navigateur d'y accéder. Lorsque Google y accède, il doit être lu dans le même cache, sans rien écrire dans le cache. –

Répondre

1

Si vous souhaitez continuer dans cette voie (je suppose que vous avez utilisé https://weblogs.asp.net/gunnarpeipman/asp-net-4-0-writing-custom-output-cache-providers comme point de départ?), vous devrez modifier GetFullPathForKey pour qu'il génère des noms de fichiers valides. How to remove illegal characters from path and filenames? vous aidera probablement à le faire. Vous devrez également modifier votre code afin qu'il ne tombe pas si deux threads essayent d'écrire dans le même fichier en même temps. De plus, vous devriez vraiment introduire l'utilisation d'un MemoryCache pour éviter de toucher le système de fichiers chaque fois qu'un appel Get à votre classe se produit. Ce sera beaucoup de travail.

Je suggère de considérer ces paquets NuGet comme une alternative. Ils font ce genre de choses hors de la boîte, et sont bien testés:

Ou tout simplement Whack un proxy inverse devant le serveur Web qui aide à la mise en cache - par exemple http://mikehadlow.blogspot.com.au/2013/05/the-benefits-of-reverse-proxy.html.