c# - ASP.NET Core Web API 检查 if-modified-since 标头不起作用,因为浏览器甚至没有提交到服务器
问题描述
我有一个控制器,它返回一个FileStreamResult
. 部分处理查看“if-modified-since”标头是否小于数据库中返回的当前日期NotModified()
或实际的FileStreamResult
. 问题是,客户端(在本例中为 Swagger)甚至没有提交到我的服务器,因此我可以根据传入的标头检查数据库日期。我没有在Startup
. 鉴于下面的代码,任何想法如何确保它提交回我的 web api 以便我可以进行数据库比较?
这是 Chrome 网络选项卡的屏幕截图。您可以看到第一个(显示为test)提交到服务器(我已禁用缓存打开),然后再次提交并由(磁盘缓存)提供服务- 从不访问服务器。
请注意,我将这些链接作为我的模板:
- https://rehansaeed.com/asp-net-core-caching-in-practice/#last-modified--if-modified-since
- https://www.geekytidbits.com/efficient-caching-dynamic-resources-asp-net-304-not-modified/
[ApiController]
public class DownloadSpecificVersion : ControllerBase
{
private readonly IDbConnectionFactory dbConnectionFactory;
public DownloadSpecificVersion( IDbConnectionFactory dbConnectionFactory ) => this.dbConnectionFactory = dbConnectionFactory;
public record Parameters
{
private string _folder;
[FromRoute]
public string Folder
{
get => _folder.KatAppFolder();
set => _folder = value;
}
[FromRoute]
public string Name { get; init; }
[FromRoute]
public string Version { get; init; }
}
[HttpGet( "/api/kat-apps/{folder}/{name}/version/{version}" )]
[SwaggerOperation(
Summary = "Download specific version of KatApp kaml file",
Description = "Download specific version of KatApp kaml file",
OperationId = "KatApps.DownloadSpecificVersion",
Tags = new[] { "KatApps" } )]
[ProducesResponseType( typeof( FileStreamResult ), StatusCodes.Status200OK )]
[ProducesResponseType( StatusCodes.Status304NotModified )]
[ProducesResponseType( typeof( ValidationProblemDetails ), StatusCodes.Status401Unauthorized )]
[ProducesResponseType( typeof( ValidationProblemDetails ), StatusCodes.Status404NotFound )]
public async Task<IActionResult> HandleAsync( [FromQuery] Parameters parameters )
{
using ( var cn = await dbConnectionFactory.CreateDataLockerConnectionAsync() )
{
var keyInfo = await cn.QueryBuilder( $@"omitted, query to find item in db" ).QueryFirstOrDefaultAsync<CacheDownloadInfo>();
return keyInfo != null
? await CachedOrModifiedAsync( keyInfo, dbConnectionFactory )
: NotFound();
}
}
}
protected async Task<IActionResult> CachedOrModifiedAsync( CacheDownloadInfo cacheDownloadInfo, IDbConnectionFactory dbConnectionFactory )
{
var lastModifiedDate = cacheDownloadInfo.LastModifiedDate.Value.ToUniversalTime();
// https://rehansaeed.com/asp-net-core-caching-in-practice/#last-modified--if-modified-since
// https://www.geekytidbits.com/efficient-caching-dynamic-resources-asp-net-304-not-modified/
var requestHeaders = HttpContext.Request.GetTypedHeaders();
// HTTP does not provide milliseconds, so remove it from the comparison
if ( requestHeaders.IfModifiedSince.HasValue && lastModifiedDate.AddMilliseconds( -lastModifiedDate.Millisecond ) <= requestHeaders.IfModifiedSince.Value )
{
return NotModified();
}
var responseHeaders = HttpContext.Response.GetTypedHeaders();
responseHeaders.LastModified = lastModifiedDate;
var fs = File.OpenRead( "c:\test.txt" ); // This is really code that gets a 'stream' from the database
return new FileStreamResult( fs, "text/plain" );
}
解决方案
$.ajax()
我的问题是我通过简单的调用在浏览器控制台中对此进行了测试。我需要ifModified: true
在配置中设置它以使用标头调用服务器if-modified-since
。
我在使用 Swagger 时发现了另一个问题。如果我设置以下内容,它似乎才有效:
responseHeaders.CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue
{
Public = true,
MustRevalidate = true,
MaxAge = new TimeSpan( 0, 0, 0 ),
};
responseHeaders.Expires = DateTime.UtcNow;
这将导致:
Cache-Control:public, must-revalidate, max-age=0 Last-Modified:Sun, 10 Jun 2012 20:19:21 GMT
推荐阅读
- python - 这是什么意思?xarray 错误:无法处理非唯一的多索引
- java - 如何在 JFrame 上显示 JTable
- python - EOFError:在导入 .tar.gz 文件时,压缩文件在到达流结束标记之前结束
- python - 相对导入和 Python 3 的问题
- javascript - 如何修复应使用 CSS 突出显示选定区域的代码
- typescript - 静态异步方法的返回类型
- python - 使用 Selenium GeckoDriver 和 Firefox 时是否可以减少内存 RAM 消耗
- kubernetes - 为 helm 模板中的每个列表成员添加后缀
- jsf - Omnifaces ViewScoped 生成一个 POST 调用
- powershell - Start-Sleep 暂停整个功能