简体   繁体   English

下载损坏的 PDF 文件

[英]Downloading corrupt PDF file

I am developing a feature in ASP.NET to download pdf file from byte[] .我正在 ASP.NET 中开发一个功能来从byte[]下载 pdf 文件。

So, we are using Winnovative.PdfConverter.GetPdfBytesFromHtmlString feature to get the pdf bytes.因此,我们使用Winnovative.PdfConverter.GetPdfBytesFromHtmlString功能来获取 pdf 字节。 In below code, the data variable is a byte[] returned by在下面的代码中, data变量是一个byte[]返回的
Winnovative.PdfConverter.GetPdfBytesFromHtmlString . Winnovative.PdfConverter.GetPdfBytesFromHtmlString

Therefore, the data variable alrady has the bytes that needs to be written in the pdf file.因此, data变量已经有需要写入pdf文件的字节了。

NOTE: When I do File.WriteAllBytes("a path", data) a pdf file is created and can be read and is not corrupt.注意:当我执行File.WriteAllBytes("a path", data)会创建一个 pdf 文件并且可以读取并且不会损坏。

The reason I want to use HttpResponse is because I want the file to be downloaded because that is what the client wants.我想使用HttpResponse的原因是因为我想要下载文件,因为这是客户端想要的。

In Short, I want the code written below to take the byte[] data variable, write it to a pdf file and download it.简而言之,我希望下面编写的代码采用byte[] data变量,将其写入 pdf 文件并下载。

Following is the code:以下是代码:

HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.ClearContent();
response.ClearHeaders();
response.Cache.SetCacheability(HttpCacheability.Private);
response.CacheControl = "private";
response.AddHeader("Content-Type", "binary/octet-stream");
response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"; size=" + (object)data.Length);
response.AddHeader("Content-Length", data.Length.ToString((IFormatProvider)CultureInfo.InvariantCulture));
response.Flush();
response.BinaryWrite(data);
response.Flush();
response.End();

When I run the Web app the download occurs smooth but the file fails to load when opened.当我运行 Web 应用程序时,下载会顺利进行,但文件在打开时无法加载。

Updating this answer in 2020 as this is how I do it today in an ASP.NET WebAPI controller.在 2020 年更新此答案,因为这就是我今天在 ASP.NET WebAPI 控制器中的做法。 This is a full ApiController example:这是一个完整的 ApiController 示例:

using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web.Http;
using MediatR;
using NLog;
using Company.Core.Enums;
using Company.Portal.DependencyResolution;
using Company.Portal.Helpers;
using Company.Services.CustomerResource;

namespace Company.Portal.Controllers
{
    [Authorize]
    [RoutePrefix("api/Commerce")]
    public class CommerceController : ApiController
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        private readonly IMediator _mediator = IoC.Container.GetInstance<IMediator>();

        [Route("Order/pdf/{orderNumber}")]
        [HttpGet]
        public async Task<HttpResponseMessage> OrderPdf(int orderNumber, string emailAddress)
        {
            var userSecurityContext = User.Identity.GetUserSecurityContext();
            Logger.Debug($"{Request.Method}|{Request.RequestUri}|{userSecurityContext}");
            HttpResponseMessage response;

            if (userSecurityContext.OrderOrigin.IsCompanyOrderOrigin())
            {
                response = Request.CreateResponse(HttpStatusCode.Forbidden, $"{userSecurityContext.OrderOrigin} not authorized");
            }
            else
            {
                var request = new GetCustomerOrderPdfRequest(orderNumber, emailAddress, userSecurityContext.OrderOrigin);
                byte[] pdfContent = await _mediator.Send(request);
                if (pdfContent == null)
                {
                    response = Request.CreateResponse(HttpStatusCode.NotFound, $"Unable to find resource. Resource {orderNumber} may not exist.");
                }
                else
                {
                    response = Request.CreateResponse(HttpStatusCode.OK);
                    response.Content = new StreamContent(new MemoryStream(pdfContent));
                    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
                    response.Content.Headers.ContentLength = pdfContent.Length;
                    if (ContentDispositionHeaderValue.TryParse($"inline; filename={userSecurityContext.OrderOrigin}-Order-{orderNumber}.pdf", out var contentDisposition))
                    {
                        response.Content.Headers.ContentDisposition = contentDisposition;
                    }
                }
            }
            return response;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM