Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在上传完成并临时保存到磁盘之前,文件上传未命中控制器_C#_Asp.net Core_.net Core_Fluentftp - Fatal编程技术网

C# 在上传完成并临时保存到磁盘之前,文件上传未命中控制器

C# 在上传完成并临时保存到磁盘之前,文件上传未命中控制器,c#,asp.net-core,.net-core,fluentftp,C#,Asp.net Core,.net Core,Fluentftp,让我们想象一下,我正在一个具有1GB存储和1GB RAM的设备上运行.NET核心API。我想直接从我的网站上传一个文件到FTP服务器,而不需要将文件缓存在内存或磁盘上。我将此功能用于下载文件,因为我基本上充当代理,在流中打开FTP文件,然后将其直接流到HttpContext.Request.Body 对于上传,我想立即点击控制器。我现在可以看到它缓存到磁盘,这可能是因为我的enablebuffer属性。我有一个常规的发布到我的.NET核心后端。控制器如下所示: [EnableBuffering]

让我们想象一下,我正在一个具有1GB存储和1GB RAM的设备上运行.NET核心API。我想直接从我的网站上传一个文件到FTP服务器,而不需要将文件缓存在内存或磁盘上。我将此功能用于下载文件,因为我基本上充当代理,在流中打开FTP文件,然后将其直接流到
HttpContext.Request.Body

对于上传,我想立即点击控制器。我现在可以看到它缓存到磁盘,这可能是因为我的
enablebuffer
属性。我有一个常规的
发布到我的.NET核心后端。控制器如下所示:

[EnableBuffering]
[RequestFormLimits(ValueLengthLimit = int.MaxValue, MultipartBodyLengthLimit = long.MaxValue)]
[HttpPost("[action]")]
public async Task<IActionResult> Upload(string path)
{
    if (!IsMultipartContentType(HttpContext.Request.ContentType))
        return BadRequest("Not multipart request");

    await _fileProvider.Upload(path);

    return Ok();
}
上传逻辑:

public async Task Upload(string path)
{
    const int buffer = 8 * 1024;

    var request = _httpContextAccessor.HttpContext.Request;
    var boundary = request.GetMultipartBoundary();
    var reader = new MultipartReader(boundary, request.Body, buffer);
    var section = await reader.ReadNextSectionAsync();

    using (var client = await _ftpHelper.GetFtpClient())
    {
        while (section != null)
        {
            var fileSection = section.AsFileSection();

            if (fileSection != null)
            {
                var fileName = fileSection.FileName;

                var uploadPath = Path.Combine(path, fileName);

                var stream = await client.OpenWriteAsync(uploadPath);
                await section.Body.CopyToAsync(stream, buffer);
            }

            section = await reader.ReadNextSectionAsync();
        }
    }
}
如果我不启用缓冲,我会得到:

System.IO.IOException:意外的流结束,内容可能已被其他组件读取

但是,通过启用缓冲,我可以看到它说:

确保可以多次读取requestBody。通常在内存中缓冲请求体将大于30K字节的请求写入磁盘

所以这部分是有道理的。然而,我该如何解决这个问题呢?如果我在
Upload()
方法的第一行设置了断点,然后开始上传,它会先上传文件,然后点击断点


我是否可以绕过此问题,使其立即命中我的控制器并开始上载到FTP服务器,而不首先保存到磁盘?

尝试使用日志输出,而不是设置断点,因为它可能会干扰上载workflow@HirasawaYui我可以保证在上传完成之前它不会击中控制器。通过构建并部署到生产环境进行测试。您将需要缓冲,但只需使用一个小的缓冲区。CopyTo中使用的默认缓冲区大小为82kb,这意味着您可以传输大型文件,而每个文件仅使用82kb的内存transfer@MalteR是的,这是正确的,但是,这并不能解决我在磁盘上缓存文件的问题。即使我删除EnableBuffering属性,它仍然会在临时保存到磁盘时首先上载文件,然后点击我的控制器。
public async Task Upload(string path)
{
    const int buffer = 8 * 1024;

    var request = _httpContextAccessor.HttpContext.Request;
    var boundary = request.GetMultipartBoundary();
    var reader = new MultipartReader(boundary, request.Body, buffer);
    var section = await reader.ReadNextSectionAsync();

    using (var client = await _ftpHelper.GetFtpClient())
    {
        while (section != null)
        {
            var fileSection = section.AsFileSection();

            if (fileSection != null)
            {
                var fileName = fileSection.FileName;

                var uploadPath = Path.Combine(path, fileName);

                var stream = await client.OpenWriteAsync(uploadPath);
                await section.Body.CopyToAsync(stream, buffer);
            }

            section = await reader.ReadNextSectionAsync();
        }
    }
}