我正在使用 ASP.NET Web API。
我想从 API(API 生成的)下载使用 C# 的 PDF。
我可以让 API 返回
byte[]
吗?对于 C# 应用程序我可以这样做吗:
byte[] pdf = client.DownloadData("urlToAPI");?
和
File.WriteAllBytes()?
最好返回其中包含 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;
}
更新来自patridge的评论: 如果其他人到达这里希望从字节数组而不是实际文件发送响应,您将需要使用
new ByteArrayContent(someData)
而不是 StreamContent
(请参阅此处)。
请注意
.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");
}
我做了以下操作:
[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;
已安装文件下载,可以存入Stream直接传文件下载
[HttpGet]
[Route("api/getFile")]
public async Task<FileResult> GetFile(string Param1,string Param2)
{
try
{
Stream stream = null;
string strURL = @"File URL";
HttpClient client = new HttpClient();
HttpResponseMessage httpResponse = await client.GetAsync(strURL);
Stream streamToReadFrom = await httpResponse.Content.ReadAsStreamAsync();
return File(streamToReadFrom, "{MIME TYPE}");
}
catch (Exception ex)
{
throw ex;
}
finally
{
}
}
我一直想知道是否有一种简单的方法可以以更......“通用”的方式下载文件。我想出了这个。
这是一个简单的
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();
}
我的尝试是:
public HttpResponseMessage GetFileFromPath2(string guid)
{
var response = new HttpResponseMessage();
MemoryStream memoryStream = new MemoryStream();
var path = "C:\test";
if (_fileHelper.ExtistFileFromPath(path, guid))
{
memoryStream = new MemoryStream(File.ReadAllBytes(Path.Combine(path, guid)));
response.StatusCode = HttpStatusCode.OK;
response.Content = new StreamContent(memoryStream);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = guid };
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Headers.AcceptRanges.Add("bytes");
}
else
{
response.StatusCode = HttpStatusCode.NoContent;
response.Content = new StringContent("File not found");
}
return response;
}