是否可以覆盖MultipartFormDataStreamProvider,以便不上传到文件系统?

我有一个ASP.Net Web API应用程序,允许客户端(HTML页面和iPhone应用程序)上传图像。 我正在使用本文所述的异步上载任务。

当我想要保存到文件系统时,一切都很有效,因为这就是这个代码在幕后看起来自动执行的操作。 但是,我不想将上传的文件保存到文件系统中。 相反,我想使用AWS SDK for .Net获取上传的流并将其传递到Amazon S3存储桶。

我已将代码设置为将流发送到AWS。 我无法弄清楚的问题是如何从Web API方法获取上传的内容流,而不是让它自动保存到磁盘。

我希望我可以在MultipartFormDataStreamProvider中覆盖一个虚拟方法,它允许我对上传的内容做其他事情,而不是保存到磁盘,但似乎没有。

有什么建议?

您可以覆盖MultipartFormDataStreamProvider的GetStream方法以返回不是文件流但是您的AWS流的流,但是有一些问题这样做(我在此不再赘述)。 相反,您可以创建一个派生自抽象基类MultipartStreamProvider的提供程序。 以下示例主要基于MultipartFormDataStreamProvider和MultipartFileStreamProvider的实际源代码。 您可以 这里查看更多详情。 示例如下:

public class CustomMultipartFormDataStreamProvider : MultipartStreamProvider { private NameValueCollection _formData = new NameValueCollection(StringComparer.OrdinalIgnoreCase); private Collection _isFormData = new Collection(); private Collection _fileData = new Collection(); public NameValueCollection FormData { get { return _formData; } } public Collection FileData { get { return _fileData; } } public override Stream GetStream(HttpContent parent, HttpContentHeaders headers) { // For form data, Content-Disposition header is a requirement ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition; if (contentDisposition != null) { // If we have a file name then write contents out to AWS stream. Otherwise just write to MemoryStream if (!String.IsNullOrEmpty(contentDisposition.FileName)) { // We won't post process files as form data _isFormData.Add(false); MyMultipartFileData fileData = new MyMultipartFileData(headers, your-aws-filelocation-url-maybe); _fileData.Add(fileData); return myAWSStream;//**return you AWS stream here** } // We will post process this as form data _isFormData.Add(true); // If no filename parameter was found in the Content-Disposition header then return a memory stream. return new MemoryStream(); } throw new InvalidOperationException("Did not find required 'Content-Disposition' header field in MIME multipart body part.."); } ///  /// Read the non-file contents as form data. ///  ///  public override async Task ExecutePostProcessingAsync() { // Find instances of HttpContent for which we created a memory stream and read them asynchronously // to get the string content and then add that as form data for (int index = 0; index < Contents.Count; index++) { if (_isFormData[index]) { HttpContent formContent = Contents[index]; // Extract name from Content-Disposition header. We know from earlier that the header is present. ContentDispositionHeaderValue contentDisposition = formContent.Headers.ContentDisposition; string formFieldName = UnquoteToken(contentDisposition.Name) ?? String.Empty; // Read the contents as string data and add to form data string formFieldValue = await formContent.ReadAsStringAsync(); FormData.Add(formFieldName, formFieldValue); } } } ///  /// Remove bounding quotes on a token if present ///  /// Token to unquote. /// Unquoted token. private static string UnquoteToken(string token) { if (String.IsNullOrWhiteSpace(token)) { return token; } if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1) { return token.Substring(1, token.Length - 2); } return token; } } public class MyMultipartFileData { public MultipartFileData(HttpContentHeaders headers, string awsFileUrl) { Headers = headers; AwsFileUrl = awsFileUrl; } public HttpContentHeaders Headers { get; private set; } public string AwsFileUrl { get; private set; } } 

由于@KiranChalla发布了他们的答案,因此在Fix 1760中引入了一个新的抽象类MultipartFormDataRemoteStreamProvider :使MultipartFormDataStreamProvider更容易使用非FileStream。 使这更容易。

该类的摘要在解释如何使用它方面做得很好:

适用于HTML文件上载的MultipartStreamProvider实现,用于将文件内容写入远程存储Stream 。 流提供程序查看Content-Disposition头字段,并根据filename参数的存在确定输出远程Stream 。 如果Content-Disposition标头字段中存在filename参数,则正文部分将写入GetRemoteStream提供的远程Stream 。 否则它将被写入MemoryStream