Stream 意外结束,内容可能已被其他组件读取。 Microsoft.AspNetCore.WebUtilities.MultipartReaderStream

问题描述 投票:0回答:13

当我尝试从请求中读取多部分内容时,出现异常,表示该内容可能已被另一个组件读取。

 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);
                }
            }
c# asp.net-core asp.net-core-2.0
13个回答
37
投票

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)
    {
    }
}

文档


19
投票

事实证明,我必须使用下面的属性来禁用表单值模型绑定。

[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)
    {
    }
}

6
投票

在我的具体情况下,我使用的是多部分边界值,该值在 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 以反映正在解析的内容中存在的实际边界值后,代码将按预期工作。


5
投票

对我的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)
    {
    }
}

2
投票

我使用了

[DisableFormValueModelBinding]
但仍然出现错误,然后我还使用:

if (Request.ContentLength == 0)
                return BadRequest();

1
投票

以防万一其他人因为这个错误而追鬼: 使用 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()

1
投票

就我而言,我添加了另一个拦截文件的过滤器。即使使用上面提到的过滤器,我仍然遇到问题。删除蜜罐终于消除了错误。

            .AddMvc(options =>
            {
                options.Filters.Add(new AuthorizeFilter());
                // .... etc
                options.AddHoneyPot(); // This was causing the problem
            })

1
投票

从客户端发送无效的表单数据时出现此错误。 这是有效的格式: 注意:最后有两个缺点和新行

<empty>
------------------------------8dac95867d24bd1
Content-Disposition: form-data; name="user_login"

<data or empty>
------------------------------8dac95867d24bd1
Content-Disposition: form-data; name="user_password"

<data or empty>
------------------------------8dac95867d24bd1
Content-Disposition: form-data; name="user_session"

<data or empty>
------------------------------8dac95867d24bd1--
<empty>

0
投票

Microsoft.AspNetCore.App 2.1.4
中存在关于此的错误。我将此软件包更新为
2.1.12
版本并解决了。


0
投票

就我而言,这是“邮递员”问题。我将文件发送到 REST 端点。在某些时候我开始收到此错误,但代码没有更改。

我在“邮递员”中再次重新选择了该文件,一切都像以前一样工作。


0
投票

如果您使用 MultipartFormDataContent 发送文件,则在另一端您将收到一个

mediaTypeHeader.Boundary.Value
,在开始和结束处带有转义的 (例如
"\"BoundaryValue\""
)。

因此,通过删除它,它开始为我工作。 对我来说,解决方法是在接收方添加此内容:

.Replace("\"", "")

mediaTypeHeader.Boundary.Value.Replace("\"", "")

0
投票

就我而言,我必须删除

[ValidateAntiForgeryToken]
属性。


0
投票

就我而言,我忘记了DisableFormValueModelBindingAttribute 中的IResourceFilter。 在 .Net7 中工作正常

© www.soinside.com 2019 - 2024. All rights reserved.