Welcome Guest Search | Active Topics | Sign In | Register

EO.Pdf.HtmlToPdf.Options Thread Safety Options
Smith-8917
Posted: Friday, May 17, 2024 2:25:37 PM
Rank: Newbie
Groups: Member

Joined: 5/17/2024
Posts: 9
We have an ASP.NET webforms application that uses the ASPXToPDF control to generate a PDF of a page. We also recently switched to using a custom distributed session state provider instead of an in memory provider. After updating EO.Pdf.HtmlToPdf.Options do not seem to be respected during the PDF conversion. For example EO.Pdf.HtmlToPdf.Options.VisibleElementIds is ignored and the full page is rendered.

I've been able to repro the issue in simplified form in a test application with out new distributed state session provider. If I comment out "Session["TestValue"] = "The quick brown fox";" the pdf generates normally (i.e. just the section identified by "print-2881").

If I uncomment this line then the full page is converted to PDF. If the session is dirty (line was uncommented), ASP.NET webforms will write to the session store at the end of Button1_Click. It looks like when it does this a thread change occurs and the ASPXToPDF code runs on a new thread with null HtmlToPdf.Options.

For the ASPXToPDF control is there a way to deterministically set the HtmlToPdf.Options values so they are independent of the thread the conversion runs on?

Code: C#
public partial class _Default : Page
 {
     protected void Page_Load(object sender, EventArgs e)
     {
         Button1.Click += Button1_Click;
         atpForm.AfterRender += AtpForm_AfterRender;
         atpForm.BeforeRender += AtpForm_BeforeRender;
     }

     private void AtpForm_BeforeRender(object sender, EventArgs e)
     {
         Console.WriteLine("debug breakpoint placeholder");
     }

     private void AtpForm_AfterRender(object sender, EventArgs e)
     {
         var pdfResult = (HtmlToPdfResult)atpForm.Result;
         string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "output.pdf");
         pdfResult.PdfDocument.Save(path);
     }

     private void Button1_Click(object sender, EventArgs e)
     {
         Session["TestValue"] = "The quick brown fox";
         EO.Pdf.HtmlToPdf.Options.VisibleElementIds = "print-2881";
         atpForm.RenderAsPDF(false);
         Response.Redirect("About.aspx", false);
     }
 }

eo_support
Posted: Monday, May 20, 2024 11:24:35 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Hi,

Can you try to set HtmlToPdf.Options inside your AtpForm_BeforeRender handler and see if it works for you?

Thanks!
Smith-8917
Posted: Monday, May 20, 2024 12:28:17 PM
Rank: Newbie
Groups: Member

Joined: 5/17/2024
Posts: 9
No, that doesn't work. A PDF of the full page is still created instead of a PDF with just the section identified by print-2881.
eo_support
Posted: Monday, May 20, 2024 12:47:00 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Are you sure that you VisibleElementIds "print-2881" is the correct value? Could it be that the Session object changed other aspect of your page logic which caused the ID of the element to be something different than "print-2881"? As a test can you try to manually put an element in your page with a fixed ID value such as "test123" and see if it works?
Smith-8917
Posted: Monday, May 20, 2024 12:52:37 PM
Rank: Newbie
Groups: Member

Joined: 5/17/2024
Posts: 9
Yes, that is the correct value. Here's the hard coded html from the page, not using any JS or client side scripting.
Code: HTML/ASPX
<section id="print-2881" class="col-md-4" aria-labelledby="librariesTitle">
      <h2 id="librariesTitle">Get more libraries</h2>
      <p>
          NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.
      </p>
      <p>
          <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301949">Learn more »</a>
      </p>
  </section>
Smith-8917
Posted: Monday, May 20, 2024 12:54:30 PM
Rank: Newbie
Groups: Member

Joined: 5/17/2024
Posts: 9
The library seems to take an implicit dependency on the consumer threading module. This seems a poor design choice as the consumer may not have control over what thread they run on (as in this case). Is it possible to provide overloads that take HtmlToPdf.Options objects so the consumer can opt out of this implicit dependency?
eo_support
Posted: Monday, May 20, 2024 1:27:08 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Hi,

The library automatically copy/save HtmlToPdf.Options between your calling thread and the thread that actually calls the HTML to PDF converter. Besides, BeforeRender handler is called directly before HtmlToPdf.Options is actually used so they are always in the same thread. As such threading should not be an issue if you set it directly in BeforeRender handler. In short, the code is designed NOT to be dependent on your threading model.

As such we can not explain why it would not work when you set it directly in BeforeRender. Our converter does not directly access your session data except for ASP.NET built-in session cookie, which should not have any impact on VisibleElementIDs. Because of this we will need to have a way to either reproduce this problem in our environment, or have access to a test environment where we can reproduce the problem in order to investigate further.

Thanks!
Smith-8917
Posted: Monday, May 20, 2024 1:39:28 PM
Rank: Newbie
Groups: Member

Joined: 5/17/2024
Posts: 9
I think there might be a slight misunderstanding here in that the session doesn't hold anything related to the PDF conversion. It is just that storing data to the session causes asp.net to write the session data to a permanent store. This is what seems to be causing a thread switch leading to possibly need PdfOptions. With no session write or using an in memory session provider the pdf conversion runs fine.

Is there a way I can submit my existing repro to you? The only external dependency you'd need is running memcached in a local docker container.
eo_support
Posted: Monday, May 20, 2024 2:18:55 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
I understand what meant by thread switching. However there is no thread switching between BeforeRender and the HTML to PDF converter because they are direct sequencial calls from the same thread. So in theory if you set it inside BeforeRender handler threading should not be an issue.

You can use our contact us page to send a test project to us. However there is a size limit --- so if it is too large and won't go through, please temporarily upload it to somehwere and then use contact us page to send us the download link.
Smith-8917
Posted: Monday, May 20, 2024 3:18:11 PM
Rank: Newbie
Groups: Member

Joined: 5/17/2024
Posts: 9
I've submitted the code repro through your contact form.

I was thinking of thread switches initiated outside the EO library. For example application code is running on thread 1 and sets the PDF options. Asp.net switches threads and then continues executing application code calling into EO libraries on thread 2 (pdf options is now null). Even though the EO library and application code didn't explicitly change threads the application framework did. Don't know that that is what is actually happening but it does seem consistent with observed behavior.
eo_support
Posted: Wednesday, May 22, 2024 11:27:52 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Thanks for the test project. We were able to find out the root issue. The issue indeed is in our library where it supposes to save and copy HtmlToPdf.Options across different thread but did not do that properly. This will be fixed in our next build.
Smith-8917
Posted: Wednesday, May 22, 2024 11:45:45 AM
Rank: Newbie
Groups: Member

Joined: 5/17/2024
Posts: 9
Thank you for the update. For our internal planning do you know approximately when your next build will be released on nuget?
eo_support
Posted: Wednesday, May 22, 2024 1:18:56 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Hi,

We should have the new build out at the end of the month.

Thanks!
Smith-8917
Posted: Tuesday, June 4, 2024 7:32:56 AM
Rank: Newbie
Groups: Member

Joined: 5/17/2024
Posts: 9
Do you have an update as to when the new build will be released on nuget?
eo_support
Posted: Tuesday, June 4, 2024 1:13:46 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Hi,

This is just to let you know that we have just posted the new version. You can download it from nuget now.

Thanks!
Smith-8917
Posted: Wednesday, June 5, 2024 2:20:42 PM
Rank: Newbie
Groups: Member

Joined: 5/17/2024
Posts: 9
Thank you. We've downloaded the new version and can confirm our issue is now fixed.
eo_support
Posted: Wednesday, June 5, 2024 2:58:53 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Great. Thanks for confirming the fix!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.