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
Gestire la cancellazione di una richiesta in streaming da Blazor
Utilizzare Copilot con Azure Cosmos DB
Utilizzare Container Queries nominali
Autenticarsi in modo sicuro su Azure tramite GitHub Actions
Ottimizzare la latenza in Blazor 8 tramite InteractiveAuto render mode
Configurare lo startup di applicazioni server e client con .NET Aspire
Usare i servizi di Azure OpenAI e ChatGPT in ASP.NET Core con Semantic Kernel
Miglioramenti agli screen reader e al contrasto in Angular
Creare una libreria CSS universale: Nav menu
Cancellare una run di un workflow di GitHub
Migliorare la scalabilità delle Azure Function con il Flex Consumption
Utilizzare il trigger SQL con le Azure Function