我使用以下属性[ResponseCache(Duration = 60)]来缓存特定的GET请求,这在我的后端.NET Core中被称为“很多”。
除了当数据库中的某些数据在60秒内发生更改时,缓存没有重新加载之外,一切正常。
是否有我必须设置的特定指令来重新加载/更新缓存?链接
来自我的控制器的代码片段示例:
[HttpGet]
[ResponseCache(Duration = 60)]
public ActionResult<SomeTyp[]> SendDtos()
{
var dtos = _repository.QueryAll();
return Ok(dtos);
}发布于 2018-11-23 17:42:23
有一个使用"ETag“、”如果-无匹配“的headers的解决方案。这个想法是使用一个代码,它可以给我们一个问题的答案:“行动的反应改变了吗?”如果控制器完全拥有特定的数据生存期,则可以这样做。
创建ITagProvider:
public interface ITagProvider
{
string GetETag(string tagKey);
void InvalidateETag(string tagKey);
}创建一个动作过滤器:
public class ETagActionFilter : IActionFilter
{
private readonly ITagProvider _tagProvider;
public ETagActionFilter(ITagProvider tagProvider)
{
_tagProvider = tagProvider ?? throw new ArgumentNullException(nameof(tagProvider));
}
public void OnActionExecuted(ActionExecutedContext context)
{
if (context.Exception != null)
{
return;
}
var uri = GetActionName(context.ActionDescriptor);
var currentEtag = _tagProvider.GetETag(uri);
if (!string.IsNullOrEmpty(currentEtag))
{
context.HttpContext.Response.Headers.Add("ETag", currentEtag);
}
}
public void OnActionExecuting(ActionExecutingContext context)
{
var uri = GetActionName(context.ActionDescriptor);
var requestedEtag = context.HttpContext.Request.Headers["If-None-Match"];
var currentEtag = _tagProvider.GetETag(uri);
if (requestedEtag.Contains(currentEtag))
{
context.HttpContext.Response.Headers.Add("ETag", currentEtag);
context.Result = new StatusCodeResult(StatusCodes.Status304NotModified);
}
}
private string GetActionName(ActionDescriptor actionDescriptor)
{
return $"{actionDescriptor.RouteValues["controller"]}.{actionDescriptor.RouteValues["action"]}";
}
}在Startup类中初始化过滤器:
public void ConfigureServices(IServiceCollection services)
{
// code above
services.AddMvc(options =>
{
options.Filters.Add(typeof(ETagActionFilter));
});
services.AddScoped<ETagActionFilter>();
services.AddSingleton<ITagProvider, TagProvider>();
// code below
}在控制器中的某个位置使用InvalidateETag方法(在修改数据的位置):
[HttpPost]
public async Task<ActionResult> Post([FromBody] SomeType data)
{
// TODO: Modify data
// Invalidate tag
var tag = $"{controllerName}.{methodName}"
_tagProvider.InvalidateETag(tag);
return NoContent();
}此解决方案可能需要更改客户端。如果使用的是fetch,则可以使用以下库:https://github.com/export-mike/f-etag。
我没有指定ITagProvider接口的实现,您需要自己编写。关于ETag和缓存的文章:https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching,https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag
https://stackoverflow.com/questions/53447908
复制相似问题