Определите конец потока в многопоточном потоке в ASP.NET Ядро 5 WebAPI

#asp.net-core-webapi

Вопрос:

Я пытаюсь создать API REST, который берет большой файл и загружает его в SharePoint. Я использую рекомендуемый Microsoft подход для загрузки больших файлов через веб-API, как показано ниже. После загрузки я помещаю их в библиотеку документов SharePoint. Поскольку это большие файлы, загрузка в SharePoint должна быть разделена на части. Для этого мне нужно знать, когда поток будет завершен (больше байтов не поступит) или длина потока заранее. Кажется, я не могу найти ни того, ни другого. В данный момент я передаю файл на диск, а затем загружаю его в SharePoint. Очевидно, что это не самый эффективный процесс. Вместо этого я хотел бы передать файл напрямую в SharePoint. Для этого мне нужно знать, когда прекратить чтение потока. Таким образом, либо нужно заранее знать длину потока, либо нужен какой-то атрибут в потоке, указывающий, что поток завершил чтение.

Входной поток от многопоточного считывателя является многопоточным потоком. Этот поток не имеет заданной длины. У него есть свойство под названием FinalBoundaryFound, которое, я думаю, я мог бы использовать, однако этот класс является внутренним классом, поэтому я не могу получить доступ к этому свойству. Доступны только свойства базового потока. Многосекционный и многопоточный редактор, похоже, не имеют индикатора.

У кого-нибудь есть какие-либо идеи о том, как я могу получить длину потока или определить, когда поток достиг своего конца?

     [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 amp;amp; contentDisposition.DispositionType.Equals("form-data") amp;amp;
                !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


                I would like to implement a while loop here that reads bytes off the stream and sends them to sharepont but
                cannot determine when to stop reading.

                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.");
    }
 

Ответ №1:

Вы можете блокировать большие файлы в Javascript и загружать их в SharePoint с помощью restapi.

Официальный документ: Загрузите файл с помощью REST API и jQuery

Блокировать большой файл

Пример кода для вашей справки.

Комментарии:

1. У меня нет проблем с дополнением кода на c#, который делает именно то, что делает java-скрипт. На самом деле именно этим я сейчас и занимаюсь. Это возможно, потому что вы знаете длину файлового потока. Так что вы знаете, сколько байтов нужно отправить. Поток многопоточности не поддерживает длину файла. Это моя проблема.