从 ContentDisposition 中丢失时如何在 MultipartStreamProvider GetStream 中获取文件大小

Posted

技术标签:

【中文标题】从 ContentDisposition 中丢失时如何在 MultipartStreamProvider GetStream 中获取文件大小【英文标题】:How to get file size in MultipartStreamProvider GetStream when missing from ContentDisposition 【发布时间】:2017-12-25 03:32:34 【问题描述】:

我创建了一个自定义 MultipartStreamProvider 来将文件存储在 Azure 文件存储中,作为旧应用程序提升和转移工作的一部分。客户端在前端使用 AngularJS,在后端使用 WebAPI。当我尝试使用 MultipartStreamProvider 时,我需要实现 GetStream 以返回要写入的流。我正在使用 cloudFile.OpenWrite,它询问将写入它的流/文件的大小。但是,在 GetStream 中,ContentDisposition.Size 是空的。有没有一种方法可以让 AngularJS 发送每个文件或后端的内容大小,也许我可以从其他地方挖掘文件流的大小?任何帮助将不胜感激。谢谢!

MultipartStreamProvider

        public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
    
        // For form data, Content-Disposition header is a requirement
         ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition;

        Console.WriteLine(files.Count);
        if (contentDisposition != null)
        
            // create default filename if its missing
            contentDisposition.FileName = (String.IsNullOrEmpty(contentDisposition.FileName) ? $"Guid.NewGuid().data" : contentDisposition.FileName);

            // We won't post process files as form data
            _isFormData.Add(false);

            CloudMultipartFileData fileData = new CloudMultipartFileData(headers, _fileRepository.BaseUrl, contentDisposition.FileName);// your - aws - filelocation - url - maybe);
            _fileData.Add(fileData);

            var azureStream = _fileRepository.GetWriteStream(contentDisposition.Size, _relativeDirectory, fileData.FileName);

            return azureStream;

            // We will post process this as form data
            _isFormData.Add(true);
        

        throw new InvalidOperationException("Did not find required 'Content-Disposition' header field in MIME multipart body part..");
    

对 Azure 的实际调用

        public override Stream GetWriteStream(long? fileSize, string relativeDirectory, string filename)
    
        var combinedRelativeDirectory = GetCloudDirectory(relativeDirectory);
        CloudFile cloudFile = combinedRelativeDirectory.GetFileReference(filename);
        return cloudFile.OpenWrite(fileSize, null, null);
    

AngularJS 文件上传代码

        /********************************** Add/Upload Photos **************************************/
    $scope.$watch('files', function (files) 
        $scope.formUpload = false;
        console.log(files);
        if (files != null) 
            for (var i = 0; i < files.length; i++) 
                $scope.errorMsg = null;
                (function (file) 
                    upload(file);
                )(files[i]);
            
        
    );

    function upload(file) 
        file.upload = Upload.upload(
            url: window.location.origin + "/api/mydocs/uploadfile?storeFolder=" + $scope.attachmentFolder + "&storeId=" + $scope.storeId + "&userId=" + $scope.currentUser.UserId,
            method: 'POST',
            headers: ,
            fields: ,
            file: file

        );

【问题讨论】:

【参考方案1】:

我最终手动将文件大小添加到标题

        function upload(file) 
        file.upload = Upload.upload(
            url: window.location.origin + "/api/mydocs/uploadfile?storeFolder=" + $scope.myFolder + "&clientId=" + $scope.clientId,
            method: 'POST',
            headers:  'file-info':file.name + "-/" + file.size ,
            fields: ,
            file: file

        );

然后在构造函数中,我用它来创建一个查找表:

    public MyCloudMultipartFormDataStreamProvider(string relativeDirectory, IEnumerable<string> lookupInfo)
    
        NewFileNames = new Dictionary<string, string>();

        _fileRepository = new CloudFileRepository();
        _relativeDirectory = relativeDirectory;
        _uploadedFilesLookup = new Dictionary<string, long>();
        foreach (var fileInfo in lookupInfo)
        
            var values = Regex.Split(fileInfo, @"-/");
            _uploadedFilesLookup.Add(values[0], Int64.Parse(values[1]));
        
    

然后从查找表中获取文件的大小并将其传递给我的 GetWriteStream 方法

            var azureStream = _fileFacade.GetWriteStream(_uploadedFilesLookup[fileName], 
                _relativeDirectory, fileData.FileName, out newFileName);

【讨论】:

以上是关于从 ContentDisposition 中丢失时如何在 MultipartStreamProvider GetStream 中获取文件大小的主要内容,如果未能解决你的问题,请参考以下文章

text contentDisposition attachment http://test.greenbytes.de/tech/tc2231/#attwithfn2231utf8

csharp contentDisposition attachment http://test.greenbytes.de/tech/tc2231/#attwithfn2231utf8

response.setHeader("Contentdisposition","attachment;filename="+URLEncoder.encode

从输入字段读取属性时 HTML 编码丢失

从支付网关回发时丢失会话

从一个屏幕移动到另一个屏幕时如何不丢失列表中的数据?