简体   繁体   中英

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

I have to send mails in my background application, for this I use Hangfire , but I have to attach a document to each mail with its recipient, the information of the document to be attached is in a table that I convert with rotativa.

My concern is when I want to convert the document into byte[] I always get that the HttpContext is null , obviously because there is no HTTP request which triggers the action while everything is in the background.

Here is my actual code:

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);

Can someone can help me initialize the httpcontext from my controller?

It looks like an issue in Rotativa lib that it has to take a controller context, github.com/webgio/Rotativa/pull/88

And you won't be able to pass the context to hangfire background process as you listed.

A work around (incase the file is not too big) might be that your hangfire process call a URL on your website which do the email sending code instead of doing the Rotativa and email sending in the hangfire background process.

I am the author of Rotativa and the owner of rotativa.io cloud service.

In the SaaS version of rotativa you can use the Nuget lib that will let you build PDFs from razor views without the need to reference Asp.net:

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

You can check cloud services as Giogio Bozio suggested, or, if you plan to use current Rotativa DLL, you could try the solution I suggested in my comment.

You code should look like this (embedded sample solution in the code you provided):

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);

Please, chek if it works for you, and don't forget to include the required references:

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

after some week with trying with rotativa i fund another solution with Itextsharp bellow how i did: 1-first all installing the package ItextSharp and ItextSharp XMLWorker
2- i designed my template in html page with the css put them in a
folder(@"C:\Templates\Credit.html"; @"C:\Templates\pdfview.css";)
3-read the html and the css with this methode

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

and use this methode to convert to 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;


    }

Thanks your hope that will help someone

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