我有一个 ASP.NET Core 控制台应用程序,作为 Windows 服务托管在用户的 PC 上,它与远程服务器通信以执行某些任务,例如将文件作为流从本地计算机上传到服务器。
远程服务器具有以下控制器操作来以流形式接收文件:
[HttpPost]
[MultipartFormData]
[DisableFormValueModelBinding]
[RequestSizeLimit(524_288_000)]
public async Task<IActionResult> Upload(CancellationToken cancellationToken)
{
if (Request.ContentType is null)
{
return BadRequest("Invalid content type");
}
var fileUploadResultCode = await
_fileService.UploadFileAsync(HttpContext.Request.Body,
Request.ContentType, cancellationToken);
return CreatedAtAction(nameof(Upload), fileUploadResultCode);
}
这是客户端上发出上传文件的 POST 请求的方法:
public async Task<int> Upload(string file)
{
string fileName = Path.GetFileName(file);
await using FileStream fileStream = File.OpenRead(file);
using MultipartFormDataContent content = new()
{
{ new StringContent("string1"), "string1" },
{ new StringContent("string2"), "string2" },
{ new StreamContent(fileStream), "file", fileName }
};
// automatically cancels the request after some time only to reproduce
// the issue
CancellationTokenSource cts = new();
try
{
cts.CancelAfter(3000);
using HttpResponseMessage response = await
_httpClient.PostAsync("api/filetransfer", content, cts.Token);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<int(cancellationToken:
cts.Token);
}
catch (Exception)
{
throw;
}
}
问题在于,虽然取消令牌在客户端方法中被激活(
cts.IsCancellationRequested = true;
),但它不会在控制器的操作中激活,因此即使请求已被取消,文件的处理仍会继续。
我发现问题出在{ new StreamContent(fileStream), "file", fileName }
线上。通过删除此行(因此,不将文件传递到流),取消令牌激活将正确传播到控制器的操作。
通过使用 Postman 调用端点(包括文件),取消令牌将正确传播到端点。所以我的代码似乎有问题,但对我来说一切似乎都是正确的。
在 ASP.NET Core 中的 multipart/form-data 中发布文件时,其他人是否遇到取消请求未到达端点的问题?
编辑: 使用简单的
while
循环替换控制器操作内的代码(检查取消令牌是否被取消)后,使用 Postman 发布多部分文件时也会出现此问题。所以,这个问题似乎与 ASP.NET Core 7 中的多部分内容有关。可能是一个错误。
我的代码是完美的,问题不是由于这里其他人建议的任何潜在问题或 ASP.NET Core 中可能的错误引起的。
这是我的开发机器上安装的一个偷偷摸摸的服务,它干扰了 http 中止请求。