PDFsharp & MigraDoc Foundation
http://forum.pdfsharp.com/

PdfDocumentRenderer.RenderDocument null reference for clone
http://forum.pdfsharp.com/viewtopic.php?f=2&t=4402
Page 1 of 1

Author:  atte902 [ Fri Nov 11, 2022 9:24 am ]
Post subject:  PdfDocumentRenderer.RenderDocument null reference for clone

I get null reference error when trying to render document that has been cloned. I create clone document because it cannot be rendered twice, and I need the clone to be stored into blob storage. The original document is returned to user.

Stack trace:
at MigraDoc.DocumentObjectModel.Visitors.VisitorBase.VisitHeaderFooter(HeaderFooter headerFooter)
at MigraDoc.DocumentObjectModel.HeaderFooter.MigraDoc.DocumentObjectModel.Visitors.IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, Boolean visitChildren)
at MigraDoc.DocumentObjectModel.HeadersFooters.MigraDoc.DocumentObjectModel.Visitors.IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, Boolean visitChildren)
at MigraDoc.DocumentObjectModel.Section.MigraDoc.DocumentObjectModel.Visitors.IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, Boolean visitChildren)
at MigraDoc.DocumentObjectModel.Sections.MigraDoc.DocumentObjectModel.Visitors.IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, Boolean visitChildren)
at MigraDoc.DocumentObjectModel.Document.MigraDoc.DocumentObjectModel.Visitors.IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, Boolean visitChildren)
at MigraDoc.DocumentObjectModel.Visitors.VisitorBase.Visit(DocumentObject documentObject)
at MigraDoc.Rendering.DocumentRenderer.PrepareDocument()
at MigraDoc.Rendering.PdfDocumentRenderer.PrepareDocumentRenderer(Boolean prepareCompletely)
at MigraDoc.Rendering.PdfDocumentRenderer.PrepareRenderPages()
at MigraDoc.Rendering.PdfDocumentRenderer.RenderDocument()

From the heap I managed to find out, that the error comes from this part of the code:
Attachment:
image.png
image.png [ 87.12 KiB | Viewed 2647 times ]

Attachment:
image2.png
image2.png [ 93.79 KiB | Viewed 2647 times ]


I have tried to add styles again for the clone, but it did not work. Are there any workarounds?

Author:  TH-Soft [ Mon Nov 14, 2022 9:32 am ]
Post subject:  Re: PdfDocumentRenderer.RenderDocument null reference for cl

Hi!
Are you using the latest version 1.51.5185-beta?
I encountered a problem with "Clone()" with an older version and fixed it.

At possible workaround: write the document to an MDDDL string and then create a new document from that string. Probably a bit slower, but should create the same effect as "Clone()".

If you provide code that allows us to replicate the issue with the latest version, then we can try to fix it.

Author:  atte902 [ Tue Nov 15, 2022 12:58 pm ]
Post subject:  Re: PdfDocumentRenderer.RenderDocument null reference for cl

TH-Soft wrote:
Are you using the latest version 1.51.5185-beta?

I was using latest stable version 1.50.5147, but now I tried that version and 1.51.5186, but neither one worked.

TH-Soft wrote:
At possible workaround: write the document to an MDDDL string and then create a new document from that string.

What is MDDDL string and how to create one?

I cannot share all my code, but here edited snipped of the code:
Code:
Document document = new Document();
document.Styles.Add(DefineStyles(document));

DefineContent(...);

var archiveItem = new AzureArchiveItem(document.ToFileBytes(), ...);
AzureArchiveService.Instance.ArchiveDocument(archiveItem);

// this prevents exception because you cannot bind other renderes to document
// "A MigraDoc document can be rendered by only one renderer, because the rendering process
// modifies its internal structure"
document.BindToRenderer(null);

return document;


This binding render to null seems to work, but is it safe to do this? My problem is that document needs to be rendered here, but also later when document is returned to user. If document could have Renderer read only property, I could use it, but it is only a private field.

ToFileBytes is extension method that creates a PdfDocumentRenderer, renders the document and saves it to MemoryStream.

Author:  () => true [ Tue Nov 15, 2022 1:46 pm ]
Post subject:  Re: PdfDocumentRenderer.RenderDocument null reference for cl

atte902 wrote:
I cannot share all my code, but here edited snipped of the code
OK, so we cannot replicate the issue.

It is by design that a document can be rendered only once. Resetting the renderer binding is a hack and rendering a second time can lead to undesired effects.

"Clone()" should be the clean way to render more than once. Give us code to replicate the exception and we will try to fix it.

MDDDL:
http://pdfsharp.net/wiki/MigraDocDDL.ashx
The DdlWriter class has WriteToString methods, the DdlReader has a DocumentFromString method. That's the workaround for Clone().

Author:  atte902 [ Wed Nov 16, 2022 8:48 am ]
Post subject:  Re: PdfDocumentRenderer.RenderDocument null reference for cl

For those that have same problem. I made extension method:
Code:
public static Document CloneByDdl(this Document document)
        {
            try
            {
                using var stream = new MemoryStream();
                var writer = new DdlWriter(stream);
                writer.WriteDocument(document); 

                stream.Position = 0;

                var reader = new DdlReader(stream);
                var clonedDocument = reader.ReadDocument();

                writer.Close();
                reader.Close();

                return clonedDocument;
            }
            catch (Exception e)
            {
                var msg = "An error occured while attempting to clone document.";
                Log.Error(msg, e);
                throw new Exception(msg, e);
            }
        }


This takes 4ms, so this seems to be the best solution.

Thanks for your help and quick answers!

Page 1 of 1 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/