Stream 意外结束,内容可能已被另一个组件读取。 Microsoft.AspNetCore.WebUtilities.MultipartReaderStream
Posted
技术标签:
【中文标题】Stream 意外结束,内容可能已被另一个组件读取。 Microsoft.AspNetCore.WebUtilities.MultipartReaderStream【英文标题】:Unexpected end of Stream, the content may have already been read by another component. Microsoft.AspNetCore.WebUtilities.MultipartReaderStream 【发布时间】:2018-09-26 18:50:57 【问题描述】:当我尝试从请求中读取多部分内容时出现异常,提示该内容可能已被另一个组件读取。
if (MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
// Used to accumulate all the form url encoded key value pairs in the
// request.
var formAccumulator = new KeyValueAccumulator();
var boundary = Request.GetMultipartBoundary();
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
var section = await reader.ReadNextSectionAsync();
while (section != null)
ContentDispositionHeaderValue contentDisposition;
var hasContentDispositionHeader =
ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
【问题讨论】:
【参考方案1】:在 asp.net core 3 中,您必须将factories.RemoveType<FormFileValueProviderFactory>();
添加到您的DisableFormValueModelBindingAttribute
属性中。
代码
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
public void OnResourceExecuting(ResourceExecutingContext context)
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<FormFileValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
public void OnResourceExecuted(ResourceExecutedContext context)
Documentation
【讨论】:
这个答案很有用,并且在我将 DotNet 核心从 2.2 迁移到 3.1 时帮助了我。我的 API 在添加 FormFileValueProviderFactory 后工作。谢谢:)【参考方案2】:原来我必须使用下面的属性来禁用表单值模型绑定。
[HttpPost]
[Route("")]
[DisableFormValueModelBinding]
public async Task<IActionResult> Post()
属性实现如下
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
public void OnResourceExecuting(ResourceExecutingContext context)
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
public void OnResourceExecuted(ResourceExecutedContext context)
【讨论】:
我喜欢使用ValueProviderFactories.RemoveType<T>()
禁用每个工厂,但它仍然给我意外错误
是的,为我解决了。这是因为DisableFormValueModelBinding
自定义过滤器允许我们阻止该方法尝试自动绑定和验证输入,这会抢先读取输入流。这允许我们稍后使用MultipartReader
来解析request.Body
。有用的参考; blog.bitscry.com/2018/03/12/…
这个答案帮助我解决了一个问题,即我尝试使用带有UploadFilesAsync(String cst, String data, String device)
的绑定,然后多部分会由于被绑定抢占而引发异常。现在它按预期工作。谢谢!
我们如何在中间件 startup.cs 类中禁用DisableFormValueModelBinding
。在 .net core 2.2 中工作?【参考方案3】:
在我的具体情况下,我使用的是 MultipartReader 解析的有效负载中不存在的多部分边界值:
// multipartBoundary is not in the contents of httpResponseContentStream.
var multipartBoundary = "batchresponse_63d0e4c7-4d49-4961-a294-3902d1730c44";
var multipartReader = new MultipartReader(multipartBoundary, httpResponseContentStream);
// Unexpected end-of-stream error used to occur here:
var multipartSection = await multipartReader.ReadNextSectionAsync(cancellationToken);
更新 multipartBoundary 以反映正在解析的内容中存在的实际边界值后,代码就会按预期工作。
【讨论】:
【参考方案4】:This 为我的 netcore 3.1 工作
你需要添加
factories.RemoveType<FormFileValueProviderFactory>();
关于这个方法
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
public void OnResourceExecuting(ResourceExecutingContext context)
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<FormFileValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
public void OnResourceExecuted(ResourceExecutedContext context)
【讨论】:
此答案与@learner 答案有何不同?【参考方案5】:我用[DisableFormValueModelBinding]
还是报错,那我也用:
if (Request.ContentLength == 0)
return BadRequest();
【讨论】:
【参考方案6】:以防万一其他人就这个错误追鬼: 使用 net5 web api 我有一个控制器
[HttpPost]
[Route("api/fileupload/reportId")]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> FileUpload(int reportId)
这不是一个好主意。它给出了上面提到的错误,我记得必须通过文件属性传递额外的数据。这为我解决了它。只是为了完整性。这很正常
[HttpPost]
[Route("api/fileupload")]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> FileUpload()
【讨论】:
【参考方案7】:Microsoft.AspNetCore.App 2.1.4
中有关于此的错误。我将此包更新为2.1.12
版本并解决了。
【讨论】:
能否提供此问题的参考资料?【参考方案8】:就我而言,这是“邮递员”问题。我将文件发送到 REST 端点。在某些时候我开始收到此错误,但代码没有更改。
我在“邮递员”中再次重新选择了这个文件,一切正常。
【讨论】:
以上是关于Stream 意外结束,内容可能已被另一个组件读取。 Microsoft.AspNetCore.WebUtilities.MultipartReaderStream的主要内容,如果未能解决你的问题,请参考以下文章
StaleObjectStateException:行已被另一个事务更新或删除?
获取“SqlParameter 已被另一个 SqlParameterCollection 包含。”使用 SqlQuery 命令时出错