ฉันใช้เว็บ ASP.NET API
ฉันต้องการดาวน์โหลด PDF ด้วย C # จาก API (ที่ API สร้างขึ้น)
ฉันขอ API ส่งคืนได้byte[]
ไหม และสำหรับแอปพลิเคชัน C # ฉันสามารถทำได้:
byte[] pdf = client.DownloadData("urlToAPI");?
และ
File.WriteAllBytes()?
ฉันใช้เว็บ ASP.NET API
ฉันต้องการดาวน์โหลด PDF ด้วย C # จาก API (ที่ API สร้างขึ้น)
ฉันขอ API ส่งคืนได้byte[]
ไหม และสำหรับแอปพลิเคชัน C # ฉันสามารถทำได้:
byte[] pdf = client.DownloadData("urlToAPI");?
และ
File.WriteAllBytes()?
คำตอบ:
ดีกว่าที่จะส่งคืน HttpResponseMessage ด้วย StreamContent ภายใน
นี่คือตัวอย่าง:
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จากความคิดเห็นโดยpatridge : หากคนอื่นมาที่นี่เพื่อต้องการส่งคำตอบจากอาร์เรย์ไบต์แทนที่จะเป็นไฟล์จริงคุณจะต้องใช้ ByteArrayContent (someData) ใหม่แทน StreamContent (ดูที่นี่ )
ฉันได้ดำเนินการดังต่อไปนี้:
[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);
}
}
ตัวอย่างด้วยIHttpActionResult
ใน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;
}
หากคุณไม่ต้องการดาวน์โหลด PDF และใช้เบราว์เซอร์ที่สร้างขึ้นในโปรแกรมดู PDF ให้ลบสองบรรทัดต่อไปนี้:
responseMsg.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
responseMsg.Content.Headers.ContentDisposition.FileName = file.FileName;
var file = GetFile(id);
. file.SomeData
เป็น Byte Array ( byte[]
) และfile.FileName
คือstring
.
หมายเหตุสำหรับ.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");
}
FileContentResult
เรียกFileDownloadName
เพื่อระบุชื่อไฟล์
ฉันเคยสงสัยว่ามีวิธีง่ายๆในการดาวน์โหลดไฟล์ด้วยวิธีอื่น ๆ ... "ทั่วไป" หรือไม่ ฉันคิดสิ่งนี้ขึ้นมา
เป็นเรื่องง่ายActionResult
ที่จะช่วยให้คุณดาวน์โหลดไฟล์จากการเรียกตัวควบคุมที่ส่งคืนIHttpActionResult
ไฟล์. ไฟล์จะถูกเก็บไว้ในไฟล์byte[] Content
. คุณสามารถเปลี่ยนเป็นสตรีมได้หากต้องการ
ฉันใช้สิ่งนี้เพื่อส่งคืนไฟล์ที่เก็บไว้ในคอลัมน์ varbinary ของฐานข้อมูล
public class FileHttpActionResult : IHttpActionResult
{
public HttpRequestMessage Request { get; set; }
public string FileName { get; set; }
public string MediaType { get; set; }
public HttpStatusCode StatusCode { get; set; }
public byte[] Content { get; set; }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage response = new HttpResponseMessage(StatusCode);
response.StatusCode = StatusCode;
response.Content = new StreamContent(new MemoryStream(Content));
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = FileName;
response.Content.Headers.ContentType = new MediaTypeHeaderValue(MediaType);
return Task.FromResult(response);
}
}
อีกวิธีในการดาวน์โหลดไฟล์คือการเขียนเนื้อหาสตรีมลงในเนื้อหาของการตอบสนองโดยตรง:
[HttpGet("pdfstream/{id}")]
public async Task GetFile(long id)
{
var stream = GetStream(id);
Response.StatusCode = (int)HttpStatusCode.OK;
Response.Headers.Add( HeaderNames.ContentDisposition, $"attachment; filename=\"{Guid.NewGuid()}.pdf\"" );
Response.Headers.Add( HeaderNames.ContentType, "application/pdf" );
await stream.CopyToAsync(Response.Body);
await Response.Body.FlushAsync();
}