是否可以覆盖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
。