aspnetcore
aspnetcore copied to clipboard
OutputCacheAttribute ignores excludeDefaultPolicy if a custom BasePolicy is defined
Is there an existing issue for this?
- [X] I have searched the existing issues
Describe the bug
If a custom Base Policy is provided during OutputCacheOptions configuration, excluding (and replacing) the default one, the OutputCacheAttribute will ignore the custom Base Policy and initialize a new OutputCachePolicyBuilder without the exclusion of the DefaultPolicy.Instance (this happens only if a PolicyName is not provided in the attribute).
This doesn't allow to set a custom base policy and use it by default. Right now, the only way to use a custom policy is to provide always a PolicyName to the OutputCacheAttribute.
This is useful for example: to define a default Base Policy that allows caching of authorized APIs (currently not allowed) and use it by default without creating, for example, a named policy "AuthorizedPolicy" or similar.
A possible solution will be to add a new Property in the OutputCacheAttribute called ExcludeDefaultPolicy (with default value set to False) and use it for the initialization of the OutputCachePolicyBuilder.
The problem is at line 79 of OutputCacheAttribute.cs: https://github.com/dotnet/aspnetcore/blob/63d2fb07e93007af1f016d447a904ce187256881/src/Middleware/OutputCaching/src/OutputCacheAttribute.cs#L79
Expected Behavior
OutputCache attribute should correctly use the default base policy configured at startup, without overriding it with DefaultPolicy.Instance.
Steps To Reproduce
Set a custom Base Cache Policy at startup (in the example I just added a policy that always caches):
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder.AddPolicy<CustomBasePolicy>(), true);
options.AddPolicy("force-cache", builder => builder.AddPolicy<CustomBasePolicy>(), true);
});
Where CustomBasePolicy is defined as follow:
public class CustomBasePolicy : IOutputCachePolicy
{
public ValueTask CacheRequestAsync(OutputCacheContext context, CancellationToken cancellation)
{
// always cache
context.EnableOutputCaching = true;
context.AllowCacheLookup = true;
context.AllowCacheStorage = true;
context.AllowLocking = true;
// Vary by any query by default
context.CacheVaryByRules.QueryKeys = "*";
return ValueTask.CompletedTask;
}
public ValueTask ServeFromCacheAsync(OutputCacheContext context, CancellationToken cancellation)
{
return ValueTask.CompletedTask;
}
public ValueTask ServeResponseAsync(OutputCacheContext context, CancellationToken cancellation)
{
var response = context.HttpContext.Response;
// Verify existence of cookie headers
if (!StringValues.IsNullOrEmpty(response.Headers.SetCookie))
{
context.AllowCacheStorage = false;
return ValueTask.CompletedTask;
}
// Check response code
if (response.StatusCode != StatusCodes.Status200OK)
{
context.AllowCacheStorage = false;
return ValueTask.CompletedTask;
}
return ValueTask.CompletedTask;
}
}
In an API Controller, simply add an OutputCache attribute, without specifying a policy name:
[HttpPut("test1")] // Using a method different than GET or HEAD, or using the Authorize attribute will always fails to cache if DefaultPolicy.Instance is used
[OutputCache]
public string TestCache()
{
return DateTime.Now.ToString();
}
[HttpPut("test2")]
[OutputCache(PolicyName="force-cache")]
public string TestCache()
{
return DateTime.Now.ToString();
}
The second API method correctly caches the output, as the custom cache policy is used, but the first one doesn't, even if the same base policy is defined as default, excluding the DefaultPolicy.Instance.
Exceptions (if any)
No response
.NET Version
7.0.100
Anything else?
No response
It looks like the same bug I fixed here: https://github.com/dotnet/aspnetcore/pull/45013 And the fix was backported to a service release https://github.com/dotnet/aspnetcore/pull/45027, and I believe it was part of 7.0.1 which is now public. Can you try with that version?
Hi @danibo86. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.
See our Issue Management Policies for more information.