如何使用 Hangfire 在 BackgroundJob 中使用 Rotativa 获取 ControllerContext 来构建 PDF

How to get ControllerContext to build PDF using Rotativa in BackgroundJob with Hangfire

我必须在我的后台应用程序中发送邮件,为此我使用 Hangfire,但我必须在每封邮件中附加一个文件及其收件人,文件的信息附加在我用 rotativa 转换的 table 中。

我担心的是,当我想将文档转换为 byte[] 时,我总是得到 HttpContextnull,显然是因为没有 HTTP 请求触发操作一切都在后台。

这是我的实际代码:

var Avis_views = new ViewAsPdf("~/Views/AvisAutomatique/ExportPdfDebit.cshtml", printa)
{
    PageMargins = new Rotativa.Options.Margins(0, 0, 0, 0),
    MinimumFontSize = 14,
    /*ageHeight=60,*/
    PageOrientation = Rotativa.Options.Orientation.Portrait,
    PageSize = Rotativa.Options.Size.A4,
};

var fileName = "DEBITADVISE_" + Numcpt + "_" + _GetTransDateTime() + ".pdf";
//var path = Path.Combine(@"C:\DocumentPdf\", fileName);
byte[] abc =  Avis_views.BuildFile(quotesController.ControllerContext);
//System.IO.File.WriteAllBytes(path, abc);
MemoryStream ms = new MemoryStream(abc);

sendemail(email, fileName, abc, emailc);

有人可以帮我从控制器初始化 httpcontext 吗?

Rotativa lib 中似乎有一个问题,它必须采用控制器上下文,github。com/webgio/Rotativa/pull/88

并且您将无法像您列出的那样将上下文传递给 hangfire 后台进程。

解决方法(如果文件不是太大)可能是您的 hangfire 进程在您的网站上调用 URL 执行电子邮件发送代码,而不是在 hangfire 中执行 Rotativa 和电子邮件发送后台进程。

我是 Rotativa 的作者和 rotativa.io 云服务的所有者。

在 SaaS 版本的 rotativa 中,您可以使用 Nuget 库,它可以让您从剃刀视图构建 PDF,而无需参考 Asp.net:

https://rotativa.io/site/blog/instructions/2020/07/31/create-pdf-in-net-core-without-aspnet.html

您可以按照 Giogio Bozio 的建议检查云服务,或者,如果您打算使用当前的 Rotativa DLL,您可以尝试我在评论中建议的解决方案。

您的代码应如下所示(您提供的代码中嵌入了示例解决方案):

var Avis_views = new ViewAsPdf("~/Views/AvisAutomatique/ExportPdfDebit.cshtml", printa)
{
    PageMargins = new Rotativa.Options.Margins(0, 0, 0, 0),
    MinimumFontSize = 14,
    /*ageHeight=60,*/
    PageOrientation = Rotativa.Options.Orientation.Portrait,
    PageSize = Rotativa.Options.Size.A4,
};

var fileName = "DEBITADVISE_" + Numcpt + "_" + _GetTransDateTime() + ".pdf";
//var path = Path.Combine(@"C:\DocumentPdf\", fileName);

// Create an instance of your controller class (in example, I guess you are using mentioned quotesController)
QuotesController controllerInstance = new QuotesController();

// Generate RouteData based in your controller (even if you are not using on in this situation, you can reference an existent one)
RouteData route = new RouteData();
// Simply change "MyAction" and "QuotesController" for the name of real action name and controller, respectively
route.Values.Add("action", "MyAction");
route.Values.Add("controller", "QuotesController");

// Generate controller context, to use in the next step
ControllerContext newContext = new ControllerContext(new HttpContextWrapper(System.Web.HttpContext.Current), route, controllerInstance);

byte[] abc =  Avis_views.BuildFile(newContext); // Here you send the generated controller context
//System.IO.File.WriteAllBytes(path, abc);
MemoryStream ms = new MemoryStream(abc);

sendemail(email, fileName, abc, emailc);

请检查它是否适合您,并且不要忘记包含所需的参考资料:

using System.Web;
using System.Web.Routing;
using System.Web.Mvc;

在尝试使用 rotativa 一周后,我用 Itextsharp 资助了另一个解决方案,下面是我的做法: 1-首先安装包 ItextSharp 和 ItextSharp XMLWorker
2- 我在 html 页面中设计了我的模板,其中 css 将它们放在
文件夹中(@"C:​​\Templates\Credit.html"; @" C:\Templates\pdfview.css";)
3-用这个方法阅读 html 和 css

public string RenderViewToString(string viewPath)
    {
        var file = new FileInfo(viewPath);
        using (StreamReader streamReader = file.OpenText())
        {
            string viewLine = "";
            var result = string.Empty;
            while ((viewLine = streamReader.ReadLine()) != null)
            {
                result = result + viewLine;
            }
            return result;
        }
    }

并使用此方法转换为 pdf:

 public byte[] GetPDF(string param1,string param2,etc...)
    {
        
        byte[] bPDF = null;
        try
        {
            pHTML = pHTML.Replace("{{parameter form the html file}}", param1);
            pHTML = pHTML.Replace("{{parameter form the html file}}", param2);
            
            MemoryStream ms = new MemoryStream();
            TextReader txtReader = new StringReader(pHTML.ToString());

            
            var image = @"C:\Templates\avis.jpg";
            iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(image);
            jpg.SpacingBefore = 10f;
            jpg.ScaleToFit(50, 50);
            jpg.Alignment =iTextSharp.text.Image.ALIGN_RIGHT;
           

            
            doc.Open();
            doc.Add(jpg);
            using (var cssMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(csstemp)))
            {
                using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(pHTML)))
                {
                    XMLWorkerHelper.GetInstance().ParseXHtml(oPdfWriter, doc, htmlMemoryStream, cssMemoryStream);
                }
            }
            //htmlWorker.StartDocument();
            //// 5: parse the html into the document  
            //htmlWorker.Parse(txtReader);

            //// 6: close the document and the worker  
            //htmlWorker.EndDocument();

            //htmlWorker.Close();
            doc.Close();

            bPDF = ms.ToArray();

            return bPDF;
        }
        catch (Exception ex)
        {
            var mess = ex.StackTrace;
            var mess2 = ex.Message;
        }

        return bPDF;


    }

感谢您希望对某人有所帮助