从HttpRequest获取文件名

时间:2019-03-03 17:05:57

标签: c# asp.net-web-api asp.net-core

基本上,我的应用程序需要能够处理大文件上传,为此,我研究了File uploads docs by Microsoft

在这里,他们提到通过流上传大文件,这听起来不错,所以我复制了文档中的代码。但是,我的问题是我无法从HttpRequest获取原始上传的文件props(FileName,Length等...)。

我已经尝试访问request.Form.Files,但是那样我会得到一个异常:IOException: Unexpected end of Stream, the content may have already been read by another component.,因为之后我尝试再次访问该请求。

完成上传后(当然具有流传输),获取FileName + Length的最佳方法是什么?

编辑:

控制器的代码当前如下所示:

[Authorize]
[Route("api/[controller]")]
public class FileController : Controller
{
    private FileManagerDbContext _context;
    public FileController(FileManagerDbContext context) {
        _context = context;
    }

    [HttpPost("upload")]
    [DisableFormValueModelBinding]
    public async Task<IActionResult> Upload()
    {
        using (var stream = System.IO.File.Create("myfile.temp"))
        {
            await Request.StreamFile(stream);
        }
        var fileToSave = new File();
        fileToSave.FileName = null;
        fileToSave.FileSize = 0;
        fileToSave.UploadDate = new DateTime();
        _context.Files.Add(fileToSave);
        _context.SaveChanges();

        return Ok(fileToSave);
    }

}

文件上传完成后,我想将一些关于上传文件的最小元数据持久化到我的数据库中。但是我无法获得必要的属性。

4 个答案:

答案 0 :(得分:1)

如果愿意,您也可以在控制器内倒回

if (request?.ContentLength != null)
{
    request.EnableRewind();

    request.Body.Seek(0, SeekOrigin.Begin);

    using (var reader = new StreamReader(request.Body, Encoding.UTF8))
    {
        body = reader.ReadToEnd();

        //Do your thing with the body content
    }

}

答案 1 :(得分:0)

如果未在控制器操作方法的顶部添加此属性,则会发生此错误。用于禁用表单值模型绑定,以控制处理 潜在的大文件。

  

[DisableFormValueModelBinding]

答案 2 :(得分:0)

好的,所以我发现一种解决方法是启用HttpRequest倒带。为此,我需要将这段代码添加到Startup.cs

app.Use(async (context, next) => {
    context.Request.EnableRewind();
    await next();
});

这样就不会抛出UnexpectedEndOfStream异常,因为可以倒带该流。

答案 3 :(得分:0)

考虑到文件具有公共URL,可以使用访问控制文件下载数据。

            var webRequest = HttpWebRequest.Create(url);

            using (var webResponse = webRequest.GetResponse())
            {
                var file_size = webResponse.Headers.Get("Content-Length");
                var file_name = webResponse.ResponseUri.Segments.Last();
            }