Я написал собственный провайдер outputcache, который сохраняет выходные данные на диске, он работает правильно, за исключением действий, украшенных AuthorizeAttribute.
Если посмотреть на проблему, решение, кажется, имеет собственный AuthorizeAttribute, который управляет кешем.
Затем я добавил свой настраиваемый атрибут AuthorizeAttribute, но, к сожалению, получаю сообщение об ошибке
"При использовании настраиваемого поставщика кэша вывода, такого как FileCacheProvider, поддерживаются только следующие политики истечения срока действия и функции кэширования: зависимости файлов , абсолютные истечения срока действия, обратные вызовы статической проверки и обратные вызовы статической подстановки."
Код:
Пользовательский поставщик OutputCache (FileCacheProvider)
public class FileCacheProvider : OutputCacheProvider
{
public string CacheLocation
{
get
{
if (ConfigurationManager.AppSettings["FileCacheLocationRelativePath"] == null)
{
throw new ApplicationException("The FileCacheLocationRelativePath AppSettings key is not configured.");
}
string strCacheLocation = ConfigurationManager.AppSettings["FileCacheLocationRelativePath"];
strCacheLocation = HttpContext.Current.Server.MapPath(strCacheLocation);
return strCacheLocation + @"\";
}
}
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();
}
private string GetFullPathForKey(string key)
{
string temp = key.Replace('/', '$');
return CacheLocation + temp;
}
}
[Serializable]
public class CacheItem
{
public object Item { get; set; }
public DateTime Expiry { get; set; }
}
Пользовательский AuthorizeAttribute (DFAuthorizeAttribute)
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class DFAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
private AuthenticationManager authentication = new AuthenticationManager();
protected void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
{
validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
}
protected void SetCachePolicy(AuthorizationContext filterContext)
{
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan(0));
cachePolicy.AddValidationCallback(CacheValidateHandler, null);
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (AuthorizeCore(filterContext.HttpContext))
{
SetCachePolicy(filterContext);
}
else if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
// auth failed, redirect to login page
filterContext.Result = new HttpUnauthorizedResult();
}
else if (authentication != null || authentication.AuthenticationData != null)
{
SetCachePolicy(filterContext);
}
else
{
ViewDataDictionary viewData = new ViewDataDictionary();
viewData.Add("Message", "You do not have sufficient privileges for this operation.");
filterContext.Result = new ViewResult { ViewName = "Error", ViewData = viewData };
}
}
}
Web.config
<caching>
<outputCache defaultProvider="FileCacheProvider">
<providers>
<add name="FileCacheProvider" type="MyNameSpace.FileCacheProvider"/>
</providers>
</outputCache>
<outputCacheSettings>
<outputCacheProfiles>
<add name="Index" duration="3600" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
Действие
[OutputCache(CacheProfile = "Index")]
[MyNameSpace.DFAuthorize]
public ActionResult Index(string pageId)
{
....
}
Любая помощь будет оценена