web-dev-qa-db-fra.com

Comment retourner un fichier en utilisant Web API?

J'utilise API Web ASP.NET.
Je souhaite télécharger un PDF avec C # à partir de l'API (généré par l'API).

Puis-je simplement demander à l'API de retourner un byte[]? et pour l'application C #, puis-je simplement faire:

byte[] pdf = client.DownloadData("urlToAPI");? 

et

File.WriteAllBytes()?
84
Kyle

Mieux vaut renvoyer HttpResponseMessage avec StreamContent à l'intérieur.

Voici un exemple:

public HttpResponseMessage GetFile(string id)
{
    if (String.IsNullOrEmpty(id))
        return Request.CreateResponse(HttpStatusCode.BadRequest);

    string fileName;
    string localFilePath;
    int fileSize;

    localFilePath = getFileFromID(id, out fileName, out fileSize);

    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
    response.Content = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read));
    response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
    response.Content.Headers.ContentDisposition.FileName = fileName;
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

    return response;
}

[~ # ~] upd [~ # ~] du commentaire de patridge : Quelqu'un d'autre devrait-il venir ici pour envoyer une réponse provenant d'un tableau d'octets au lieu d'un fichier réel, vous allez vouloir utiliser le nouveau ByteArrayContent (someData) au lieu de StreamContent (voir ici ).

144
Regfor

J'ai fait l'action suivante:

[HttpGet]
[Route("api/DownloadPdfFile/{id}")]
public HttpResponseMessage DownloadPdfFile(long id)
{
    HttpResponseMessage result = null;
    try
    {
        SQL.File file = db.Files.Where(b => b.ID == id).SingleOrDefault();

        if (file == null)
        {
            result = Request.CreateResponse(HttpStatusCode.Gone);
        }
        else
        {
            // sendo file to client
            byte[] bytes = Convert.FromBase64String(file.pdfBase64);


            result = Request.CreateResponse(HttpStatusCode.OK);
            result.Content = new ByteArrayContent(bytes);
            result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            result.Content.Headers.ContentDisposition.FileName = file.name + ".pdf";
        }

        return result;
    }
    catch (Exception ex)
    {
        return Request.CreateResponse(HttpStatusCode.Gone);
    }
}
32

Exemple avec IHttpActionResult dans ApiController.

[HttpGet]
[Route("file/{id}/")]
public IHttpActionResult GetFileForCustomer(int id)
{
    if (id == 0)
      return BadRequest();

    var file = GetFile(id);

    IHttpActionResult response;
    HttpResponseMessage responseMsg = new HttpResponseMessage(HttpStatusCode.OK);
    responseMsg.Content = new ByteArrayContent(file.SomeData);
    responseMsg.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
    responseMsg.Content.Headers.ContentDisposition.FileName = file.FileName;
    responseMsg.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
    response = ResponseMessage(responseMsg);
    return response;
}

Si vous ne souhaitez pas télécharger le PDF et utiliser un navigateur intégré PDF le visualiseur sera remplacé, supprimez les deux lignes suivantes:

responseMsg.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
responseMsg.Content.Headers.ContentDisposition.FileName = file.FileName;
7
Ogglas

Juste une note pour .Net Core: Nous pouvons utiliser le FileContentResult et définir le contentType sur application/octet-stream si nous voulons envoyer les octets bruts. Exemple:

[HttpGet("{id}")]
public IActionResult GetDocumentBytes(int id)
{
    byte[] byteArray = GetDocumentByteArray(id);
    return new FileContentResult(byteArray, "application/octet-stream");
}
2
Amir Shirazi