从 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