3

我有以下控制器:

[NoCache]
public class AccountController : Controller
{
    [Authorize(Roles = "admin,useradmin")]
    public ActionResult GetUserEntitlementReport(int? userId = null)
    {
        var byteArray = GenerateUserEntitlementReportWorkbook(allResults);

        return File(byteArray,
                System.Net.Mime.MediaTypeNames.Application.Octet,
                "UserEntitlementReport.xls");
    }
}

public class NoCache : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var response = filterContext.HttpContext.Response; 
        response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        response.Cache.SetValidUntilExpires(false);
        response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        response.Cache.SetCacheability(HttpCacheability.NoCache);
        response.Cache.SetNoStore();
        base.OnResultExecuting(filterContext);
    }
}

如您所见,控制器是用[NoCache]属性装饰的。

有什么办法可以防止这个属性被应用到GetUserEntitlementReport动作上?

我知道我可以在控制器级别删除属性,但这不是我最喜欢的解决方案,因为控制器包含许多其他操作,我不想将属性单独应用于每个操作。

4

3 回答 3

4

您可以创建一个新属性,该属性可用于单个操作以选择退出在控制器级别指定的 NoCache。

[AttributeUsage(AttributeTargets.Class |
                AttributeTargets.Method,
                AllowMultiple = false,
                Inherited = true)]
public sealed class AllowCache : Attribute { }

标记您要允许缓存的任何操作[AllowCache]

然后在代码中,如果该属性不存在,NoCacheAttribute则仅禁用缓存AllowCache

public class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        var actionDescriptor = filterContext.ActionDescriptor;
        bool allowCaching = actionDescriptor.IsDefined(typeof(AllowCache), true) ||
            actionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowCache), true);

        if(!allowCaching)
        {
            //disable caching.
        }
    }
}
于 2013-02-12T16:32:40.007 回答
2

您可以将一个属性应用于操作。那就是[OverrideActionFilters]。

[NoCache]
public class AccountController : Controller
{
    [Authorize(Roles = "admin,useradmin")]
    [OverrideActionFilters]
    public ActionResult GetUserEntitlementReport(int? userId = null)
    {
        var byteArray = GenerateUserEntitlementReportWorkbook(allResults);

        return File(byteArray,
                System.Net.Mime.MediaTypeNames.Application.Octet,
                "UserEntitlementReport.xls");
    }
}
于 2015-02-04T20:55:46.013 回答
0

这可以通过实现和注册自定义过滤器提供程序来完成。作为起点,我将从FilterAttributeFilterProvider派生并覆盖 GetFilters 以在适当时删除 NoCache 属性。

于 2013-02-12T15:53:31.387 回答