简体   繁体   中英

Get PDF from WebAPI and download from UI, but data gets corrupted

I call a Web API Controller from my UI which then gets a report from SSRS. It inserts the bytes in the content of the response and sends it to the UI where it gets downloaded as a PDF.

Inside my Web API Controller I write the report bytes to a test PDF file to inspect the contents of the pdf and to see if the data is correct, which it is. But when the PDF gets downloaded from my UI and I open it, I get a blank paged document. When I inspect the reponse content in Fiddler, I can see that the data is corrupted and doesn't match the test PDF file data.

Server side:

[HttpPost]
public HttpResponseMessage GetInstancePdf(InstancePdfModel model) {
  var bytes = _digitalFormService.GetInstancePdf(model.ClientGuid, model.InstanceGuid, model.InstanceVersion);

  File.WriteAllBytes(@ "c:\temp\test.pdf", bytes);

  var response = Request.CreateResponse();

  response.Content = new ByteArrayContent(bytes);
  response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue(DispositionTypeNames.Inline) {
    FileName = "file.pdf"
  };
  response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

  return response;
}

Client side:

$scope.downloadPdf = function(instance) {
  $scope.isBusy = true;
  digitalFormService.getInstancePdf(instance.instanceGuid, instance.instanceVersion).then(function(data) {
    if (data.status === 200) {
      const file = new Blob([data.data], {
        type: data.headers("Content-Type")
      });
      if (navigator.appVersion.toString().indexOf(".NET") > 0) {
        window.navigator.msSaveBlob(file, (`${instance.name} ${(new Date()).toLocaleString()}`).replace(",", ""));
      } else {
        //trick to download, store a file having its URL
        const fileUrl = URL.createObjectURL(file);
        const a = document.createElement("a");
        a.href = fileUrl;
        a.target = "_blank";
        a.download = (`${instance.name} ${(new Date()).toLocaleString()}`).replace(",", "");
        document.body.appendChild(a);
        a.click();
      }
    } else {
      debugger;
    }
    $scope.isBusy = false;
  });
};

function getInstancePdf(instanceGuid, instanceVersion) {
  var data = {
    clientGuid: digitalFormConfig.clientToken,
    instanceGuid: instanceGuid,
    instanceVersion: instanceVersion
  };
  return $http({
    url: digitalFormConfig.serverUrl +
      "api/DigitalForm/GetInstancePdf",
    dataType: "json",
    data: data,
    method: "POST"
  }).then(function(response) {
      return response;
    },
    function() {
      return $q.reject("No Data");
    });
}

I expect my downloaded PDF to be an informational document, matching the test PDF file saved inside the Web API Controller, but I get a blank document instead (same number of pages as test file, but blank).

I used Fiddler to inspect the response body. When I save the response body from within Fiddler as a pdf - everything is fine. So I am sure my server side code is correct. The problem must be somewhere on the client side.

Any help? Thanks.

I found the mistake. The bug was in the client side service. Code should look as follows:

function getInstancePdf(instanceGuid, instanceVersion) {
    var data = {
        clientGuid: digitalFormConfig.clientToken,
        instanceGuid: instanceGuid,
        instanceVersion: instanceVersion
    };
    return $http({
        responseType: "arraybuffer",
        url: digitalFormConfig.serverUrl +
            "api/DigitalForm/GetInstancePdf",
        dataType: "json",
        data: data,
        method: "POST"
    }).then(function (response) {
            return response;
        },
        function () {
            return $q.reject("No Data");
        });
}

The line responseType: "arraybuffer", was omitted previously.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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