【问题标题】:Detecting file size with MultipartFormDataStreamProvider before file is saved?在保存文件之前使用 MultipartFormDataStreamProvider 检测文件大小?
【发布时间】:2015-12-16 17:22:21
【问题描述】:

我们使用MultipartFormDataStreamProvider来保存客户端上传的文件。我有一个硬性要求,即文件大小必须大于 1KB。最简单的做法当然是将文件保存到磁盘然后查看文件不幸的是我不能这样做。将文件保存到磁盘后,我无法访问它,因此我需要先查看文件,然后再将其保存到磁盘。我一直在查看流提供程序的属性,试图找出文件的大小,但不幸的是我没有成功。

我正在使用的测试文件是 1025 字节。

MultipartFormDataStreamProvider.BufferSize 为 4096
Headers.ContentDisposition.Size 为空
内容长度为空

有没有办法在文件保存到文件系统之前确定文件大小?

【问题讨论】:

    标签: file-upload asp.net-web-api asp.net-web-api2


    【解决方案1】:

    多亏了关系,我才能够制定解决方案。我在链接中使用了他的代码作为基础,我只是添加了更多的异步/等待优点:)。我想添加解决方案以防万一它对其他人有帮助:

        private async Task SaveMultipartStreamToDisk(Guid guid, string fullPath)
        {
            var user = HttpContext.Current.User.Identity.Name;
    
            var multipartMemoryStreamProvider = await Request.Content.ReadAsMultipartAsync();
    
            foreach (var content in multipartMemoryStreamProvider.Contents)
            {
                using (content)
                {
                    if (content.Headers.ContentDisposition.FileName != null)
                    {
                        var existingFileName = content.Headers.ContentDisposition.FileName.Replace("\"", string.Empty);
    
                        Log.Information("Original File name was {OriginalFileName}: {guid} {user}", existingFileName, guid,user);
    
                        using (var st = await content.ReadAsStreamAsync())
                        {
                            var ext = Path.GetExtension(existingFileName.Replace("\"", string.Empty));
                            List<string> validExtensions = new List<string>() { ".pdf", ".jpg", ".jpeg", ".png" };
                            //1024 = 1KB
                            if (st.Length > 1024 && validExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase))
                            {
                                var newFileName = guid + ext;
                                using (var fs = new FileStream(Path.Combine(fullPath, newFileName), FileMode.Create))
                                {
                                    await st.CopyToAsync(fs);
                                    Log.Information("Completed writing {file}: {guid} {user}", Path.Combine(fullPath, newFileName), guid, HttpContext.Current.User.Identity.Name);
                                }
                            }
                            else
                            {
                                if (st.Length < 1025)
                                {
                                   Log.Warning("File of length {FileLength} bytes was attempted to be uploaded: {guid} {user}",st.Length,guid,user);
                                }
                                else
                                {
                                    Log.Warning("A file of type {FileType} was attempted to be uploaded: {guid} {user}", ext, guid,user);
                                }
                                var responseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest)
                                {
                                    Content =
                                        st.Length < 1025
                                            ? new StringContent(
                                                $"file of length {st.Length} does not meet our minumim file size requirements")
                                            : new StringContent($"a file extension of {ext} is not an acceptable type")
                                };
                                throw new HttpResponseException(responseMessage);
                            }
                        }
                    }
                }
            }
    

    【讨论】:

    • 我想获取长度时遇到 System.ObjectDisposedException 的错误。什么问题?
    • @SaraN 看起来您在处理对象后尝试检查长度(st)。检查您的“使用”语句以确保在检查其长度之前您没有处置该对象。错位的花括号肯定会导致它。自从我编写代码以来,我们已经将代码投入生产,我们没有遇到过此类问题。
    【解决方案2】:

    您也可以在不使用MultipartFormDataStreamProvider 的情况下读取请求内容。在这种情况下,所有请求内容(包括文件)都将在内存中。我已经在this link 给出了一个如何做到这一点的例子。

    在这种情况下,您可以读取文件大小的标题或读取流并检查文件大小。如果它满足您的标准,则只将其写入所需的位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      • 2011-05-14
      相关资源
      最近更新 更多