Home > OS >  How to return PDF content from another HttpResponseMessage to the browser?
How to return PDF content from another HttpResponseMessage to the browser?

Time:08-30

I am in the process of creating a proxy server that makes a request to a PDF Blob link then takes the request to setup its HttpResponse Header which we sent to the client. This diagram should explain

enter image description here

As of now, I am successful at making the request to get the pdf content however I am not sure how to send that back to the user. I have followed other Stackoverflow post such as this one : enter image description here

What I am actually returning to the client

enter image description here

Here is the code I am using to create this proxy endpoint

        [AllowAnonymous]
        [HttpGet("openPDF")]
        public async Task<HttpResponseMessage> OpenPDF([FromQuery] string url)
        {
            var _httpClient = _httpClientFactory.CreateClient();
            var response = await _httpClient.GetAsync(url);
            var stream = await response.Content.ReadAsStreamAsync();

            HttpResponseMessage message = new HttpResponseMessage(HttpStatusCode.OK);
            message.Content = new StreamContent(stream);
            message.Content.Headers.ContentLength = stream.Length;
            message.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

            return message;
        }

EDIT

Ok so this actually sends back the PDF when I write the proxy like this

        [AllowAnonymous]
        [HttpGet("openPDF")]
        public async Task<FileStreamResult> OpenPDF([FromQuery] string url)
        {
            var fileStream = new MemoryStream();

            var _httpClient = _httpClientFactory.CreateClient();

            var file = await _httpClient.GetStreamAsync(url).ConfigureAwait(false);
            await file.CopyToAsync(fileStream);

            fileStream.Position = 0;
            
            return File(fileStream, "application/pdf", "filename.pdf");
        }

The problem is I want to update the content-disposition to inline so I can force this to open in the browser instead of downloading.So I decided to take the filestream and injecting that in the httpResponseMessage.content instead but that still didn't work. It would continue to send me a json file

        [AllowAnonymous]
        [HttpGet("openPDF")]
        public async Task<HttpResponseMessage> OpenPDF([FromQuery] string url)
        {
            var fileStream = new MemoryStream();

            var _httpClient = _httpClientFactory.CreateClient();

            var file = await _httpClient.GetStreamAsync(url).ConfigureAwait(false);
            await file.CopyToAsync(fileStream);

            fileStream.Position = 0;
            

            HttpResponseMessage message = new HttpResponseMessage(HttpStatusCode.OK);
            message.Content = new StreamContent(fileStream);
            message.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

            return message;
        }

To be honest, I thought defining the content-type should suffice but guess not

CodePudding user response:

This is pretty straight forward for .NET 6... suspect it should be roughly the same for .NET 4x... This uses the NuGet package Azure.Storage.Blobs

https://github.com/Azure/azure-sdk-for-net/blob/Azure.Storage.Blobs_12.13.1/sdk/storage/Azure.Storage.Blobs/README.md

[HttpGet("stream")]
public async Task GetBlobAsync()
{
    var url = new Uri("https://path.to.blob.content/xxx");
    var blobClient = new BlobClient(url);
    Response.Headers.Add("Content-Type", "application/pdf");
    Response.Headers.Add("Content-Disposition", @"attachment;filename=""intended file name.pdf""");
    await blobClient.DownloadToAsync(Response.Body);

}
  • Related