我有一些奇怪的问题,只发生在 1 个用户身上,比如说 50 个。 AFAIK 他正在使用 Chrome
当他上传文件时,Unexpected end of Stream, the content may have already been read by another component.
被抛出
这是我的端点:
[HttpPost]
public async Task<JsonResult> UploadFile(IFormFile file, int type, string otherParam)
问题是我有中间件记录每个请求,所以它正在读取请求并将正文位置设置为 0
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Services;
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Internal;
using Serilog;
using Newtonsoft.Json;
using Common.Users;
public class LoggerMiddleware
{
private readonly RequestDelegate next;
public LoggerMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext ctx)
{
var request = await FormatRequest(ctx.Request, ctx);
Log.Information(request);
await next(ctx);
}
//hack
private string[] endpoints_with_passwords = new string[] { "/Account/ChangePassword", "/Login" };
private async Task<string> FormatRequest(HttpRequest request, HttpContext ctx)
{
Log.Information("Entering Logging Middleware");
request.EnableRewind();
var length = Convert.ToInt32(request.ContentLength);
// in order to prevent having content of large files in logs...
if (length > 30000)
return $"file with length: {length} sent by User: '{ctx?.User?.Identity?.Name}'";
var buffer = new byte[length];
await request.Body.ReadAsync(buffer, 0, buffer.Length);
var bodyAsText = Encoding.UTF8.GetString(buffer);
// "hack" in order to do not log passwords
if (endpoints_with_passwords.Contains(request.Path.Value))
{
Log.Information("endpoints with password");
try
{
var data = JsonConvert.DeserializeObject<LoginModel>(bodyAsText);
var ip = request.HttpContext.Connection.RemoteIpAddress;
bodyAsText = $"IP: {ip} - UserName: {data?.UserName}";
}
catch (Exception ex)
{
EmailService.SendExceptionEmail(ex);
Log.Error(ex.Message);
}
}
Log.Information("Body Position = 0");
request.Body.Position = 0;
return $"User: '{ctx?.User?.Identity?.Name}' {Environment.NewLine} {request.Scheme} {request.Host}{request.Path} {Environment.NewLine} {request.QueryString} {Environment.NewLine} {bodyAsText}";
}
}
我以为早点回来
if (length > 30000)
return $"file with length: {length} sent by User: '{ctx?.User?.Identity?.Name}'";
可能会导致问题,但是当文件太大时,我会收到Request body too large.
所以这是不同的错误
这是显示差异的SeriLog
。原木: 其他用户上传工作正常:
2020-01-22 14:35:13.003 +01:00 [INF] User: 'A'
http localhost:5004/File/AddAttachment/1/attachment
?_=1579699970169
------WebKitFormBoundarywlRNAu9AuOB6xBUD
Content-Disposition: form-data; name="file"; filename="some.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
2020-01-22 14:35:13.083 +01:00 [INF] Route matched with {action = "AddAttachment", controller = "File"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.JsonResult] AddAttachment(Microsoft.AspNetCore.Http.IFormFile, Int32, System.String) on controller Controllers.FileController (APP).
2020-01-22 14:35:13.083 +01:00 [INF] Authorization was successful.
坏了,由这个(上面提到的(一个特定的用户发送:
2020-01-24 16:29:24.677 +01:00 [INF] User: 'B'
http localhost:5004/File/AddAttachment/1/attachment
?_=1579711474176
2020-01-24 16:29:24.677 +01:00 [INF] Route matched with {action = "AddAttachment", controller = "File"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.JsonResult] AddAttachment(Microsoft.AspNetCore.Http.IFormFile, Int32, System.String) on controller Controllers.FileController (APP).
2020-01-24 16:29:24.677 +01:00 [INF] Authorization was successful.
2020-01-24 16:29:27.381 +01:00 [ERR] 01/24/2020 16:29:25: Exception! (...) Unexpected end of Stream, the content may have already been read by another component.
有人知道可能出现什么问题吗?或者如何调试?
.NET Core 2.1
我们通过 JS 发布这些文件。
编辑: 关于GH https://github.com/dotnet/aspnetcore/issues/18087 的问题
此问题可能是由用户中断文件上传引起的。你为什么不尝试像那样重现这个问题呢?
- 开始上传大文件
- 关闭浏览器选项卡
- 预期错误