如何使用Web API返回文件?

Kyl*_*yle 87 c# asp.net-web-api

我正在使用ASP.NET Web API.
我想从API(API生成)下载带有C#的PDF.

我可以让API返回byte[]吗?对于C#应用程序,我可以这样做:

byte[] pdf = client.DownloadData("urlToAPI");? 
Run Code Online (Sandbox Code Playgroud)

File.WriteAllBytes()?
Run Code Online (Sandbox Code Playgroud)

Reg*_*for 151

最好使用StreamContent返回HttpResponseMessage.

这是一个例子:

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;
}
Run Code Online (Sandbox Code Playgroud)

UPD从评论帕特里奇:如果任何人来到这里找送出去,从一个字节数组,而不是实际文件的回应,你会想用新的ByteArrayContent(someData),而不是StreamContent(见这里).

  • 如果其他人到这里寻找从字节数组而不是实际文件发出响应,你将要使用`new ByteArrayContent(someData)`而不是`StreamContent`(参见[here](http:/ /stackoverflow.com/a/12468615/48700)). (45认同)
  • 我想指出正确的 MediaTypeHeaderValue 是至关重要的,如果你有不同的文件类型,你可以像这样让它动态。(其中 fileName 是一个字符串,文件类型以 .jpg、.pdf、docx 等结尾。) var contentType = MimeMapping.GetMimeMapping(fileName); response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType); (3认同)
  • 首先 - 此代码将导致异常,因为您要新建两个指向同一文件的 FileStream 对象。第二件事是您不想使用“Using”语句,因为一旦变量超出范围,.NET 就会处理它,并且您将收到有关关闭底层连接的错误消息。 (2认同)

小智 33

我做了以下行动:

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 对于大文件,这不是一个好主意,因为它将整个图像加载到内存中。流选项更好。 (2认同)

Ami*_*azi 22

请注意.Net Core:如果我们想发送原始字节,我们可以使用FileContentResult并将 contentType 设置为application/octet-stream。例子:

[HttpGet("{id}")]
public IActionResult GetDocumentBytes(int id)
{
    byte[] byteArray = GetDocumentByteArray(id);
    return new FileContentResult(byteArray, "application/octet-stream");
}
Run Code Online (Sandbox Code Playgroud)

  • 这非常有用,此外,如果您想控制文件名,“FileContentResult”上有一个名为“FileDownloadName”的属性来指定文件名 (8认同)

Ogg*_*las 7

IHttpActionResultin中的示例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;
}
Run Code Online (Sandbox Code Playgroud)

如果您不想下载PDF并使用内置在PDF查看器中的浏览器,请删除以下两行:

responseMsg.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
responseMsg.Content.Headers.ContentDisposition.FileName = file.FileName;
Run Code Online (Sandbox Code Playgroud)