简体   繁体   English

MultipartReader 问题,内容已被另一个组件读取

[英]MultipartReader issue, content already been read by another component

Implementing "Upload large files with streaming" ( https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-6.0 ) gives me this error:实施“使用流媒体上传大文件”( https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-6.0 )给我这个错误:

Unexpected end of Stream, the content may have already been read by another component. Stream 意外结束,内容可能已被另一个组件读取。

It happens when executing reader.ReadNextSectionAsync():它在执行 reader.ReadNextSectionAsync() 时发生:

[HttpPost]
[DisableFormValueModelBinding]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UploadPhysical()
{
    if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
    {
       ModelState.AddModelError("File",
           $"The request couldn't be processed (Error 1).");
           return BadRequest(ModelState);
        }

    var boundary = MultipartRequestHelper.GetBoundary(
       MediaTypeHeaderValue.Parse(Request.ContentType),
       _defaultFormOptions.MultipartBoundaryLengthLimit);
    var reader = new MultipartReader(boundary, HttpContext.Request.Body);
    var section = await reader.ReadNextSectionAsync();

After hours of trying to find an answer i decided to post the issue here.经过数小时试图找到答案后,我决定在这里发布问题。

The DisableFormValueModelBinding filter won't solve this issue. DisableFormValueModelBinding 过滤器不能解决这个问题。

public void OnResourceExecuting(ResourceExecutingContext context)
{            
  var factories = context.ValueProviderFactories;
  factories.RemoveType<FormValueProviderFactory>();
  factories.RemoveType<FormFileValueProviderFactory>();
  factories.RemoveType<JQueryFormValueProviderFactory>();            
}

I am using .NET 5.0, with a Razor and Mvc Controller application.我正在使用 .NET 5.0、Razor 和 Mvc Controller 应用程序。

It seems that you were referring the.Net Core 3.x sample.您似乎指的是 .Net Core 3.x 示例。 Here is the sample code for.Net 5:这是.Net 5的示例代码:

    [HttpPost]
    [Route(nameof(UploadLargeFile))]
    public async Task<IActionResult> UploadLargeFile()
    {
        var request = HttpContext.Request;

        // validation of Content-Type
        // 1. first, it must be a form-data request
        // 2. a boundary should be found in the Content-Type
        if (!request.HasFormContentType ||
            !MediaTypeHeaderValue.TryParse(request.ContentType, out var mediaTypeHeader) ||
            string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
        {
            return new UnsupportedMediaTypeResult();
        }

        var reader = new MultipartReader(mediaTypeHeader.Boundary.Value, request.Body);
        var section = await reader.ReadNextSectionAsync();

        // This sample try to get the first file from request and save it
        // Make changes according to your needs in actual use
        while (section != null)
        {
            var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
                out var contentDisposition);

            if (hasContentDispositionHeader && contentDisposition.DispositionType.Equals("form-data") &&
                !string.IsNullOrEmpty(contentDisposition.FileName.Value))
            {
                // Don't trust any file name, file extension, and file data from the request unless you trust them completely
                // Otherwise, it is very likely to cause problems such as virus uploading, disk filling, etc
                // In short, it is necessary to restrict and verify the upload
                // Here, we just use the temporary folder and a random file name

                // Get the temporary folder, and combine a random file name with it
                var fileName = Path.GetRandomFileName();
                var saveToPath = Path.Combine(Path.GetTempPath(), fileName);

                using (var targetStream = System.IO.File.Create(saveToPath))
                {
                    await section.Body.CopyToAsync(targetStream);
                }

                return Ok();
            }

            section = await reader.ReadNextSectionAsync();
        }

        // If the code runs to this location, it means that no files have been saved
        return BadRequest("No files data in the request.");
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM