Microsoft.AspNetCore.WebUtilities.MultipartReaderStream的流意外结束 [英] Unexpected end of stream at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream

查看:346
本文介绍了Microsoft.AspNetCore.WebUtilities.MultipartReaderStream的流意外结束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

System.IO.IOException: Unexpected end of stream.
at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.<ReadAsync>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.<DrainAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.WebUtilities.MultipartReader.<ReadNextSectionAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at AspNetCoreFileUpload.Controllers.FileUploadController.<Index>d__0.MoveNext() 
in C:\\GitHub\\StackOverflow\\LargeFileUploadController\\FileUploadController.cs:line 29

复制: https://github.com/bigfont/StackOverflow/tree/master/LargeFileUploadController

表格

<form action = ""/FileUpload"" method=""post"" enctype=""multipart/form-data"">
    <label for=""myfile1"">File</label>
    <input type=""file"" name=""myFile1"" />
    <label for=""myfile2"">File</label>
    <input type=""file"" name=""myFile2"" />
    <input type=""submit"" value=""Send"" />
</form>

控制器

public class FileUploadController : Controller
{
    [HttpPost]
    public async Task<IActionResult> Index()
    {
        var boundary = GetBoundary(Request.ContentType);
        var reader = new MultipartReader(boundary, Request.Body);

        try
        {
            var section = await reader.ReadNextSectionAsync();
        }
        catch (System.Exception ex)
        {
            return new OkObjectResult(new { ex = ex.ToString() });
        }

        return new OkObjectResult(new { message = "Done" });
    }

    private static string GetBoundary(string contentType)
    {
        var elements = contentType.Split(' ');
        var element = elements.Where(entry => entry.StartsWith("boundary=")).First();
        var boundary = element.Substring("boundary=".Length);
        // Remove quotes
        if (boundary.Length >= 2 && 
            boundary[0] == '"' && boundary[boundary.Length - 1] == '"')
        {
            boundary = boundary.Substring(1, boundary.Length - 2);
        }
        return boundary;
    }
}

推荐答案

最近我几乎遇到了同样的异常.我之所以说几乎是因为他们实际上将异常重命名为Unexpected end of Stream, the content may have already been read by another component.,这实际上意味着某些东西已经消耗了主体流.以下更改的注释使我们对正在发生的事情有了了解:

I got almost the same exception recently. I'm saying almost because they actually renamed the exception to Unexpected end of Stream, the content may have already been read by another component., which actually means that something already consumed the body stream. The comments of the following change gives us the understanding of what's happening:

捕手在3月23日发表了评论

... MVC模型联编程序读取表单并缓冲多部分片段 为您服务,因此使用 MultipartReader ...

...The MVC model binder reads the form and buffers the multipart segments for you, so there's no point in re-parsing request body with the MultipartReader...

所以,问题是如何禁用默认的表单绑定(读取请求表单)?

So, the question is how to disable the default form binding (reading the request form)?

我在此 Mvc.FileUpload示例中找到了DisableFormValueModelBindingAttribute属性会禁用表单绑定,这是这样的:

I found the DisableFormValueModelBindingAttribute attribute in this Mvc.FileUpload sample which disables the form binding and this is what it looks like:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        var formValueProviderFactory = context.ValueProviderFactories
                .OfType<FormValueProviderFactory>()
                .FirstOrDefault();
        if (formValueProviderFactory != null)
        {
            context.ValueProviderFactories.Remove(formValueProviderFactory);
        }

        var jqueryFormValueProviderFactory = context.ValueProviderFactories
            .OfType<JQueryFormValueProviderFactory>()
            .FirstOrDefault();
        if (jqueryFormValueProviderFactory != null)
        {
            context.ValueProviderFactories.Remove(jqueryFormValueProviderFactory);
        }
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
    }
}

如果您需要更多信息,可以查看以下内容:

If you want some more information, you can check out the following:

  • Create a filter/sample that shows how to remove the form value providers (rynowak opened this issue on Apr 26)
  • Sample: Issues with Antiforgery + Form + File Uploads (rynowak opened this issue on Apr 26)

仅供参考-如前所述, MVC模型联编程序读取表格,但是在哪里可以找到结果.结果可以在具有FilesHttpRequest.Form中找到.

Just for info - as commented before, the MVC model binder reads the form, but where can one find the results. The results can be found in the HttpRequest.Form, which has Files.

这篇关于Microsoft.AspNetCore.WebUtilities.MultipartReaderStream的流意外结束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆