Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Add support for VaryByQueryKey #2894
Browse files Browse the repository at this point in the history
  • Loading branch information
JunTaoLuo committed Oct 18, 2016
1 parent 3004fb8 commit 792dd23
Show file tree
Hide file tree
Showing 9 changed files with 422 additions and 171 deletions.
10 changes: 9 additions & 1 deletion src/Microsoft.AspNetCore.Mvc.Core/CacheProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class CacheProfile
/// <summary>
/// Gets or sets the duration in seconds for which the response is cached.
/// If this property is set to a non null value,
/// the "max-age" in "Cache-control" header is set in the
/// the "max-age" in "Cache-control" header is set in the
/// <see cref="Microsoft.AspNetCore.Http.HttpContext.Response" />.
/// </summary>
public int? Duration { get; set; }
Expand All @@ -36,5 +36,13 @@ public class CacheProfile
/// Gets or sets the value for the Vary header in <see cref="Microsoft.AspNetCore.Http.HttpContext.Response" />.
/// </summary>
public string VaryByHeader { get; set; }

/// <summary>
/// Gets or sets the query keys to vary by.
/// </summary>
/// <remarks>
/// <see cref="VaryByQueryKeys"/> requires the response cache middleware.
/// </remarks>
public string[] VaryByQueryKeys { get; set; }
}
}
24 changes: 24 additions & 0 deletions src/Microsoft.AspNetCore.Mvc.Core/Internal/ResponseCacheFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.ResponseCaching;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
Expand All @@ -21,6 +22,7 @@ public class ResponseCacheFilter : IActionFilter, IResponseCacheFilter
private ResponseCacheLocation? _cacheLocation;
private bool? _cacheNoStore;
private string _cacheVaryByHeader;
private string[] _cacheVaryByQueryKeys;

/// <summary>
/// Creates a new instance of <see cref="ResponseCacheFilter"/>
Expand Down Expand Up @@ -73,6 +75,18 @@ public string VaryByHeader
set { _cacheVaryByHeader = value; }
}

/// <summary>
/// Gets or sets the query keys to vary by.
/// </summary>
/// <remarks>
/// <see cref="VaryByQueryKeys"/> requires the response cache middleware.
/// </remarks>
public string[] VaryByQueryKeys
{
get { return _cacheVaryByQueryKeys ?? _cacheProfile.VaryByQueryKeys; }
set { _cacheVaryByQueryKeys = value; }
}

/// <inheritdoc />
public void OnActionExecuting(ActionExecutingContext context)
{
Expand Down Expand Up @@ -110,6 +124,16 @@ public void OnActionExecuting(ActionExecutingContext context)
headers[HeaderNames.Vary] = VaryByHeader;
}

if (VaryByQueryKeys != null)
{
var responseCachingFeature = context.HttpContext.Features.Get<IResponseCachingFeature>();
if (responseCachingFeature == null)
{
throw new InvalidOperationException(Resources.FormatVaryByQueryKeys_Requires_ResponseCachingMiddleware(nameof(VaryByQueryKeys)));
}
responseCachingFeature.VaryByQueryKeys = VaryByQueryKeys;
}

if (NoStore)
{
headers[HeaderNames.CacheControl] = "no-store";
Expand Down
16 changes: 16 additions & 0 deletions src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/Microsoft.AspNetCore.Mvc.Core/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -376,4 +376,7 @@
<data name="FormCollectionModelBinder_CannotBindToFormCollection" xml:space="preserve">
<value>The '{0}' cannot bind to a model of type '{1}'. Change the model type to '{2}' instead.</value>
</data>
<data name="VaryByQueryKeys_Requires_ResponseCachingMiddleware" xml:space="preserve">
<value>'{0}' requires the response cache middleware.</value>
</data>
</root>
12 changes: 11 additions & 1 deletion src/Microsoft.AspNetCore.Mvc.Core/ResponseCacheAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ public bool NoStore
/// </summary>
public string VaryByHeader { get; set; }

/// <summary>
/// Gets or sets the query keys to vary by.
/// </summary>
/// <remarks>
/// <see cref="VaryByQueryKeys"/> requires the response cache middleware.
/// </remarks>
public string[] VaryByQueryKeys { get; set; }

/// <summary>
/// Gets or sets the value of the cache profile name.
/// </summary>
Expand Down Expand Up @@ -117,6 +125,7 @@ public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
_noStore = _noStore ?? selectedProfile?.NoStore;
_location = _location ?? selectedProfile?.Location;
VaryByHeader = VaryByHeader ?? selectedProfile?.VaryByHeader;
VaryByQueryKeys = VaryByQueryKeys ?? selectedProfile?.VaryByQueryKeys;

// ResponseCacheFilter cannot take any null values. Hence, if there are any null values,
// the properties convert them to their defaults and are passed on.
Expand All @@ -125,7 +134,8 @@ public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
Duration = _duration,
Location = _location,
NoStore = _noStore,
VaryByHeader = VaryByHeader
VaryByHeader = VaryByHeader,
VaryByQueryKeys = VaryByQueryKeys,
});
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.AspNetCore.Mvc.Core/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"Microsoft.AspNetCore.Hosting.Abstractions": "1.1.0-*",
"Microsoft.AspNetCore.Http": "1.1.0-*",
"Microsoft.AspNetCore.Mvc.Abstractions": "1.1.0-*",
"Microsoft.AspNetCore.ResponseCaching.Abstractions": "1.0.0-*",
"Microsoft.AspNetCore.Routing": "1.1.0-*",
"Microsoft.AspNetCore.Routing.DecisionTree.Sources": {
"type": "build",
Expand Down
Loading

0 comments on commit 792dd23

Please sign in to comment.