È ansible sovrascrivere MultipartFormDataStreamProvider in modo che non salvi i caricamenti sul file system?

Ho un’applicazione Web API ASP.Net che consente ai client (pagine html e app per iPhone) di caricare immagini. Sto utilizzando un’attività di caricamento asincrono come descritto in questo articolo .

Tutto funziona alla grande quando voglio salvare nel file system perché questo è ciò che questo codice fa automaticamente, dietro le quinte sembra. Ma, non voglio salvare i file caricati nel file system. Invece, voglio prendere lo stream caricato e passarlo a un bucket Amazon S3 utilizzando l’SDK AWS per .Net.

Ho impostato il codice per inviare lo streaming ad AWS. Il problema che non riesco a capire è come ottenere il stream di contenuti caricato dal metodo API Web invece di salvarlo automaticamente su disco.

Speravo che ci fosse un metodo virtuale che potrei scavalcare in MultipartFormDataStreamProvider che mi permetterebbe di fare qualcos’altro con il contenuto caricato diverso dal salvataggio su disco, ma sembra che non ci sia.

Eventuali suggerimenti?

Potresti sovrascrivere il metodo GetStream di MultipartFormDataStreamProvider per restituire un stream che non è un stream di file ma il tuo stream AWS, ma ci sono alcuni problemi in tal senso (che non approfondirò qui). Invece è ansible creare un fornitore derivante dalla class di base astratta MultipartStreamProvider. L’esempio seguente è fortemente basato sul codice sorgente effettivo di MultipartFormDataStreamProvider e MultipartFileStreamProvider. Puoi controllare qui e qui per maggiori dettagli. Campione di seguito:

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; } } 

Poiché @KiranChalla ha pubblicato la risposta, nella Fix 1760 è stata introdotta una nuova class astratta MultipartFormDataRemoteStreamProvider : Make MultipartFormDataStreamProvider è più semplice da utilizzare con non FileStreams. per renderlo più facile.

Il riassunto della class fa un buon lavoro nello spiegare come usarlo:

Un’implementazione MultipartStreamProvider adatta per l’uso con caricamenti di file HTML per la scrittura di contenuti di file su un Stream archiviazione remoto. Il provider di stream esamina il campo dell’intestazione Content-Disposition e determina un Stream remoto di output in base alla presenza di un parametro filename. Se un parametro filename è presente nel campo dell’intestazione Content-Disposition, la parte body viene scritta su un Stream remoto fornito da GetRemoteStream . Altrimenti è scritto su MemoryStream .