【问题标题】:problem showing PDF in Blazor page from byte array在 Blazor 页面中从字节数组显示 PDF 的问题
【发布时间】:2021-04-11 20:06:37
【问题描述】:

我已经阅读了有关如何将存储在 SQL Server db 中的字节数组作为varbinary 并在 Blazor 网站上显示为 PDF 的所有建议。我在 ASP.Net 中取得了成功,背后有 aspx 页面和代码,但我似乎找不到适合 Blazor 的组合(ShowPDF.razor 和背后的代码ShowPDF.razor.cs

这是我在后面代码中的变体:

  1. aReport.ReportDocument 正在从 DB 中返回 aReport.DocumentSize 的字节数组

     FileStreamResult GetPDF()
     {
         var pdfStream = new System.IO.MemoryStream();
         this.rdb = new ReportData();
         aReport = rdb.GetWithReport(1);
    
         pdfStream.Write(aReport.ReportDocument, 0, aReport.DocumentSize);
         pdfStream.Position = 0;
         return new FileStreamResult(pdfStream, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/pdf"));
     }
    

OR 2. 将二进制数组直接转为 base 64 编码:

return Convert.ToBase64String(aReport.ReportDocument);

虽然这两个进程返回数据,但我无法找到如何设置剃须刀页面来显示结果。我试过了:

<object src="@Url.Action("GetPDF")"/> 

和其他变种都没有成功。

谢谢!

【问题讨论】:

    标签: pdf byte blazor


    【解决方案1】:

    好的,我终于找到了解决方案。 ShowPDF.razor.cs 页面后面的代码是:

    public partial class ShowPDF: ComponentBase
    {
        private IReportData rdb;       // the database
        private ReportModel aReport;   // report model 
    
        /*
        aReport.ReportDocument holds the byte[]
        */
        string GetPDF(int ReportId)
        {
            this.rdb = new ReportData();
            aReport = rdb.GetWithReport(ReportId);
            return "data:application/pdf;base64," + Convert.ToBase64String(aReport.ReportDocument);
        }
    }
    
    

    ShowPDF.razor 页面是:

    @page "/ShowPDF"
    @page "/ShowPDF/{Report:int}"
    
    
    @code {
        [Parameter]
        public int Report { get; set; }
    }
    <embed src="@GetPDF(Report)" visible="false" width="1500" height="2000" />
    

    【讨论】:

      【解决方案2】:

      恐怕此解决方案不适用于中型或大型 PDF 文件。没有人系统地将图像源设置为 base64 字符串。 PDF文件应该是一样的。浏览器会喜欢在单独的线程中下载 PDF,而不是在 HTML 代码呈现中。

      在 Blazor 中,这可以使用 custom middleware 轻松实现。

      namespace MyMiddlewares
      {
          public class ShowPdf
          {
              public ShowPdf(RequestDelegate next)
              {
                  //_next = next; no call to _next.Invoke(context) because the handler is at the end of the request pipeline, so there will be no next middleware to invoke.
              }
      
              public async Task Invoke(HttpContext context)
              {
                  byte[] pdfBytes = getPdfFromDb(context.Request.Query["pdfid"]);
                  context.Response.ContentType = "application/pdf";
      
                  context.Response.Headers.Add("Content-Disposition",
                                      "attachment; " +
                                      "filename=\"mypdf.pdf\"; " +
                                      "size=" + pdfBytes.Length + "; " +
                                      "creation-date=" + DateTime.Now.ToString("R").Replace(",", "") + "; " +
                                      "modification-date=" + DateTime.Now.ToString("R").Replace(",", "") + "; " +
                                      "read-date=" + DateTime.Now.ToString("R").Replace(",", ""));
                  await context.Response.Body.WriteAsync(pdfBytes);
              }
          }
      
          public static class ShowPdfExtensions
          {
              public static IApplicationBuilder UseShowPdf(this IApplicationBuilder builder)
              {
                  return builder.UseMiddleware<ShowPdf>();
              }
          }
      }
      

      在 Startup.cs 的 Configure 方法中,添加(在 app.UseStaticFiles(); 之前)

      app.MapWhen(
          context => context.Request.Path.ToString().Contains("ShowPdf.mdwr", StringComparison.InvariantCultureIgnoreCase),
          appBranch => {
              appBranch.UseShowPdf();
          });
      

      因此,此 URL 将下载 PDF 文件:/ShowPdf.mdwr?pdfid=idOfMyPdf

      如果需要嵌入,可以在 PDF 查看器中使用此 URL。

      【讨论】:

      • 谢谢。我完全同意你的看法,我试图在 Blazor 中找到一种方法来使用 context.Response 以及所有这些但从未成功过,并且因为数据库中有历史悠久的大型 pdf 文件,我需要回复用户并提供指向带有 .Net aspx 页面的 web 位置。我不熟悉中间件概念,只是复制和粘贴您提供的解决方案对我没有帮助,直到我了解更多。再次感谢您的指导,如果您能获得付费帮助,请通过 wbaeck@earthlink.net 与我联系
      • 我终于有时间了解中间件的概念并实现了您提供的这个解决方案。非常感谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-04
      • 1970-01-01
      相关资源
      最近更新 更多