【问题标题】:How to return PDF content from another HttpResponseMessage to the browser?如何从另一个HttpResponseMessage返回PDF内容给浏览器?
【发布时间】:2022-12-30 17:42:16
【问题描述】:

我正在创建一个代理服务器,它向 PDF Blob 链接发出请求,然后接受请求来设置我们发送给客户端的 HttpResponse 标头。这张图应该解释

截至目前,我已成功发出获取 pdf 内容的请求,但我不确定如何将其发回给用户。我关注了其他 Stackoverflow 帖子,例如这篇帖子:https://stackoverflow.com/a/43232581/10541061

我将图表第 3 步中的响应消息转换为流,并在新的 HttpResponseMessage 内容中将其发回。但我得到的不是 PDF 内容,而是一个 json 文件

我要返回给客户的东西

我实际上返回给客户的是什么

这是我用来创建此代理端点的代码

        [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;
        }

编辑

好的,当我这样写代理时,这实际上会发回 PDF

        [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");
        }

问题是我想将content-disposition更新为inline,这样我就可以强制在浏览器中打开而不是下载。所以我决定获取文件流并将其注入httpResponseMessage.content,但仍然没有。不工作。它会继续向我发送一个 json 文件

        [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;
        }

老实说,我认为定义内容类型就足够了,但我猜还不够

【问题讨论】:

    标签: c# azure pdf dotnet-httpclient http-proxy


    【解决方案1】:

    这对于 .NET 6 来说非常简单......怀疑它对于 .NET 4x 应该大致相同......这使用了 NuGet 包 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);
    
    }
    

    【讨论】:

      【解决方案2】:

      对于.NET 4x。

      尝试添加:

      result.Content.Headers.ContentDisposition =
      new ContentDispositionHeaderValue("inline")
      {
         FileName = "filename.pdf"
      };
      

      【讨论】:

        猜你喜欢
        • 2017-07-11
        • 2019-03-24
        • 1970-01-01
        • 2013-02-24
        • 1970-01-01
        • 2013-10-07
        • 1970-01-01
        • 1970-01-01
        • 2015-05-27
        相关资源
        最近更新 更多