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
Inference di dati strutturati da testo con Semantic Kernel e ASP.NET Core Web API
Persistere la ChatHistory di Semantic Kernel in ASP.NET Core Web API per GPT
Supporto ai tipi DateOnly e TimeOnly in Entity Framework Core
Gestire la cancellazione di una richiesta in streaming da Blazor
C# 12: Cosa c'è di nuovo e interessante
Change tracking e composition in Entity Framework
Utilizzare Copilot con Azure Cosmos DB
Potenziare Azure AI Search con la ricerca vettoriale
Creazione di plugin per Tailwind CSS: espandere le Funzionalità del Framework
Sfruttare MQTT in cloud e in edge con Azure Event Grid
Aggiungere interattività lato server in Blazor 8
I più letti di oggi
- Effettuare il log delle chiamate a function di GPT in ASP.NET Web API
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
- Creare una libreria CSS universale: Cards
- Eseguire script pre e post esecuzione di un workflow di GitHub