Effettuare l'upload di file multipli con ASP.NET Web API

di Marco De Sanctis, in ASP.NET Web API,

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

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi