ASP.NET Web API supporta l'upload di file nell'ambito di una request Multipart tramite la classe MultipartFormDataStreamProvider. Si tratta di un oggetto che restituisce uno stream utilizzato poi dal framework per salvare il contenuto del body inviato dal browser.
L'utilizzo è piuttosto semplice. Immaginiamo di avere una form di questo tipo:
<form method="post" enctype="multipart/form-data" action="@Url.HttpRouteUrl("DefaultApi", new { controller = "upload" })"> <input type="file" id="upload" name="upload" multiple /> <br /> <input type="submit" /> </form>
Come possiamo notare, essa contiene al suo interno un Input di upload, con supporto anche a file multipli, e invia il contenuto in POST all'indirizzo del nostro UploadController. Il controller, a sua volta, contiene la logica per la ricezione dei file:
public class UploadController : ApiController { public async Task<HttpResponseMessage> PostFileAsync() { if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } var rootPath = HttpContext.Current.Server.MapPath("~/App_Data/"); var provider = new MultipartFormDataStreamProvider(rootPath); await this.Request.Content.ReadAsMultipartAsync(provider); return Request.CreateResponse(HttpStatusCode.OK, string.Join(";", provider.FileData.Select(x => Path.GetFileName(x.LocalFileName)))); } }
Questa action, che risponde alle richieste in POST, innanzi tutto effettua una verifica sulla tipologia di richiesta pervenuta. Nel caso in cui sia di tipo Multipart, crea un'istanza di MultipartFormDataStreamProvider passando il folder fisico in cui dovranno essere memorizzati i file. Successivamente il metodo ReadAsMultiPartAsync effettua il parsing della richiesta e sfrutta il provider per ottenere gli stream tramite cui memorizzare i file. L'ultima operazione consiste nel ritornare i LocalFileName in risposta al browser.
Come ultima nota, vale la pena sottolineare che il file viene salvato con un nome del tipo "BodyPart_{GUID}" autogenerato, invece di sfruttare il valore dell'header Content-Disposition. Si tratta di una best practice dal punto di vista della sicurezza, ma nulla ci vieta di memorizzare questa informazione separatamente in un database e associarla al nome del file generato, così che poi possiamo riproporre il nome originale come hint in caso di successivo download.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Paginare i risultati con QuickGrid in Blazor
Ottimizzare le pull con Artifact Cache di Azure Container Registry
Utilizzare Azure Cosmos DB con i vettori
Popolare una classe a partire dal testo, con Semantic Kernel e ASP.NET Core Web API
Disabilitare automaticamente un workflow di GitHub (parte 2)
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione
Bloccare l'esecuzione di un pod in mancanza di un'artifact attestation di GitHub
Eseguire script pre e post esecuzione di un workflow di GitHub
Gestione dell'annidamento delle regole dei layer in CSS
Supportare lo HierarchyID di Sql Server in Entity Framework 8
Recuperare App Service cancellati su Azure