【发布时间】:2017-06-26 12:25:36
【问题描述】:
我已经为我的网站设置了自定义输出缓存。一切都按预期工作,我可以看到包含二进制文件的缓存文件夹。当我访问该站点时,我会获取缓存页面并按应有的方式呈现。
问题是当我尝试使用谷歌站长工具渲染页面时,谷歌无法访问BundleConfig~/bundles/styles/maincss/中生成的css路径,javascript路径也是如此。当我访问这两个路径时,我会看到缩小的 JS 和 CSS 文件,并且浏览器确实可以正确呈现页面。
这带来了一个问题,因为现在当我使用移动测试工具测试页面时,我发现这些页面不适合移动设备。出于某种原因,Google 无法访问这些路径,尽管当我在网站管理员工具中运行网络抓取时,它确实对用户有利,但对 Google-bot 不利。
这在我不使用自定义输出缓存时有效,只使用默认输出缓存。
知道如何解决这个问题。
自定义输出缓存代码:
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>
缓存类:
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();
}
}
}
【问题讨论】:
-
@mjwills 我用代码更新了问题。
-
如果你在
FileStream fileStream = File.OpenWrite(filePath);之前和之后都放了Thread.Sleep(5000)刷新你的浏览器缓存,重新启动 IIS 然后在两个不同的浏览器(比如 Chrome 和 Firefox)中同时加载相同的 JS 资源您是否会因为两件事同时尝试写入文件而收到错误消息? -
@mjwills 我没有收到错误,Google 无法访问它。我在网站管理员工具中启动了几次抓取,但仍然无法访问它。我可以用我的浏览器访问它。当 Google 访问它时,它应该从同一个缓存中读取,而不是向缓存中写入任何内容。
-
@mjwills 我得到进程无法访问文件'C:\Users\Idan\Desktop\projectx\projectx_project\projectxx\Cache\a2$bundles$styles$maincss$',因为它正在被使用由另一个进程。'
-
我也得到 System.NotSupportedException: 'The given path's format is not supported.'。在 Mozilla Firefox 中使用。
标签: c# asp.net caching outputcache