首页 > 解决方案 > 在 C# .Net 5 中分块文件

问题描述

我有大型视频文件,我试图将其分解成块并在服务器端重新组合。我一直在遵循本文中的建议,但我遇到了一些问题。

在捆绑块并通过网络发送它们的代码中,我有以下代码:

     using (var client = new HttpClient(clientHandler))
        {
            var requestUri = ApiHelper.GetUrl("api/uploadFile");
            client.BaseAddress = new Uri(requestUri);
            client.DefaultRequestHeaders.Clear();
            client.DefaultRequestHeaders.Add(Constants.ApiKeyHeaderName, Constants.RoadLivesApiAppKey);

            using (var content = new MultipartFormDataContent())
            {
                var fileBytes = System.IO.File.ReadAllBytes(fileName);
                var fileContent = new ByteArrayContent(fileBytes);
                fileContent.Headers.ContentDisposition = new
                    ContentDispositionHeaderValue("attachment")
                {
                    FileName = Path.GetFileName(fileName)
                };
                content.Add(fileContent);

                try
                {
                    var result = client.PostAsync(requestUri, content).Result;
                    rslt = true;
                }
                catch (Exception ex)
                {
                    rslt = false;
                }
            }
        }

在服务器端,我试图将该内容作为字节数组取出,以便在上传所有内容时重新组合文件。链接的文章建议 using Request.Files,它在 .NET 5 中不存在。我尝试过using ,Request.Form.Files但整体Request.Form看起来是空的。

关于如何ByteArrayContent从 Request 对象中获取信息有什么建议吗?符合我的Request.ContentLength预期,但我不确定我可以从哪里获得这些数据。

我试图ByteArrayContentRequest.Body下面的选项中获取,但它没有按预期工作。

        byte[] bodByteArray;
        MemoryStream ms = new MemoryStream();
        Request.BodyReader.CopyToAsync(ms);
        //Request.Body.CopyToAsync(ms);
        bodByteArray = ms.ToArray();

标签: c#asp.net-mvc.net-5chunks

解决方案


一切都简单得多。这是一个示例:
服务器:

using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Example.Controllers
{
    [ApiController]
    [Route("api/v1/[controller]")]
    public class UploadController : ControllerBase
    {
        [HttpPost]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public async Task PostAsync(
            CancellationToken cancellationToken = default)
        {
            byte[] bytes;

            // To get bytes, use this code (await is required, you missed it)
            // But I recommend working with Stream in order not to load the server's RAM.
            using (var memoryStream = new MemoryStream())
            {
                await Request.BodyReader.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false);
                bytes = memoryStream.ToArray();
            }

            // use bytes here
        }
    }
}

客户:

using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Example.Apis
{
    public partial class ExampleApi
    {
        public async Task UploadAsync(
            string path,
            CancellationToken cancellationToken = default)
        {
            using var client = new HttpClient();

            using var request = new HttpRequestMessage(
                HttpMethod.Post,
                new Uri("https://localhost:5001/api/v1/upload"))
            {
                Content = new StreamContent(File.OpenRead(path)),
            };
            
            using var response = await client.SendAsync(
                request, cancellationToken).ConfigureAwait(false);

            response.EnsureSuccessStatusCode();
        }
    }
}

PS 除了示例,我建议您了解 Streams 作为处理大文件的正确方法。


推荐阅读