3

I currently use Gembox.Document to read content from PDF documents. I have a class library that houses it all and a self hosted .NET Core 3.1 service that references it. I query the service with the PDF data and it responds with the content. I now want to move this functionality to an azure function (v3) instead, but I am running into the following error:

Could not load file or assembly 'PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.

To simplify it I have moved only the essential parts into the azure function which you can see below:

public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
    ILogger log)
{
    ComponentInfo.SetLicense("FREE-LIMITED-KEY");
    ComponentInfo.FreeLimitReached += (sender, args) => args.FreeLimitReachedAction = FreeLimitReachedAction.ContinueAsTrial;

    try
    {
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        ParseRequest data = JsonConvert.DeserializeObject<ParseRequest>(requestBody);

        StringBuilder sb = new StringBuilder();

        using (var ms = new MemoryStream(data.Data))
        {
            // Load document from file's path.
            var document = DocumentModel.Load(ms, LoadOptions.PdfDefault);

            foreach (var childElement in document.GetChildElements(true, ElementType.Paragraph))
            {
                sb.AppendLine(childElement.Content.ToString());
            }
        }

        return new OkObjectResult(sb.ToString());
    }
    catch (Exception e)
    {
        return new OkObjectResult("Unable to read document");
    }
}

Is this a restriction of azure functions? I have read several conflicting things which suggest it can and can't be done as it's using a WPF dll. For the record, the GemBox website provides an example for creating a PDF document in an azure function: https://www.gemboxsoftware.com/document/examples/create-word-pdf-on-azure-functions-app-service/5901. So I don't see why I wouldn't be able to read one too!

Thanks!

EDIT 1:

As per mu88's comment, I have changed the .csproj file to the below and it hasn't helped.

enter image description here

Mario Z
  • 4,328
  • 2
  • 24
  • 38
Murphybro2
  • 2,207
  • 1
  • 22
  • 36
  • Just to make sure: are you using `` and `true`? – mu88 Nov 18 '20 at 12:46
  • @mu88 please see the update, I tried your suggestion but it didn't helped. – Murphybro2 Nov 18 '20 at 12:56
  • Don't know much about azure, but it would make sense if WPF dll is not available by default in azure function, since it's server component and WPF is UI framework. Maybe copy all those dlls explicitly together with your main dll. – Evk Nov 18 '20 at 13:39

2 Answers2

1

I reached out to GemBox support and they responded with the following:

Unfortunately, GemBox.Document uses WPF for reading PDF files. So, even though you can write PDF files on Azure Functions, I’m afraid you cannot read them.

But also, I should point out that PDF reader in GemBox.Document never left the BETA stage, it has limited usage. For more information, please check the Support level for reading PDF format (beta) section.

Instead, I would suggest you try out GemBox.Pdf, see its Reading example. With GemBox.Pdf you can read and write PDF files on Azure Functions.

Last, in the long term, we plan to replace the current (internal) implementations of both PDF reader (BETA) and PDF writer in GemBox.Document with a newer implementation that’s contained in GemBox.Pdf without changing the public API of GemBox.Document. But that will not be done in the current year and for later I cannot say at this moment.

Alas, it is not possible with GemBox.Document.. yet.

Murphybro2
  • 2,207
  • 1
  • 22
  • 36
0

GemBox.Document has this issue (it might be dependent on .net Framework component), but GemBox.Pdf works fine as below.

I tested it using the GemBox.Pdf nuget with the below Function and it works fine for both creating and loading pdf in deployed Function app.

enter image description here

Create PDF:

        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            ComponentInfo.SetLicense("FREE-LIMITED-KEY");

            using (var document = new PdfDocument())
            {
                // Add a page.
                var page = document.Pages.Add();

                // Write a text.
                using (var formattedText = new PdfFormattedText())
                {
                    formattedText.Append("Hello World!");

                    page.Content.DrawText(formattedText, new PdfPoint(100, 700));
                }

                var fileName = "Output.pdf";
                var options = SaveOptions.Pdf;
                using (var stream = new MemoryStream())
                {
                    document.Save(stream, options);
                    return new FileContentResult(stream.ToArray(), "application/pdf") { FileDownloadName = fileName };
                }
            }
        }

enter image description here

LoadPDF:

        [FunctionName("Function3")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            ComponentInfo.SetLicense("FREE-LIMITED-KEY");

            try
            {
                StringBuilder sb = new StringBuilder();
                using (var document = PdfDocument.Load(req.Body))
                {
                    foreach (var page in document.Pages)
                    {
                        sb.AppendLine(page.Content.ToString());
                    }
                }

                return new OkObjectResult(sb.ToString());
            }
            catch (Exception e)
            {
                return new ExceptionResult(e, true);
            }
        }
krishg
  • 5,935
  • 2
  • 12
  • 19
  • Thanks for the response. I'm afraid we don't have a license for GemBox.Pdf, only for GemBox.Document. The GemBox.Document package allows you to read PDF documents, which is all we need for PDFs, so GemBox.Pdf is not required. Following the link included in the question, I am also able create PDF documents with no issue, but it is reading them that causes the issue. – Murphybro2 Nov 18 '20 at 20:14
  • If you would like to emulate a closer example, I suggest adding GemBox.Document instead, and then attempting to read a stored PDF document from a byte array. My example code simply receives a PDF as a byte array in a POST, and attempts to load it. – Murphybro2 Nov 18 '20 at 20:17
  • Ok I will do using GemBox.Document. – krishg Nov 18 '20 at 20:53
  • I tried with `GemBox.Document` and yes it has the same error as you reported. Looks like `GemBox.Document` is using some .net Framework dependent component which of course has issue in .net core. However `GemBox.Pdf` works fine for loading pdf too (updated my answer to include read pdf example which works). So, unfortunately you need to reach Gembox support to report this issue and discrepancy between `GemBox.Document` and `GemBox.Pdf`. – krishg Nov 19 '20 at 11:50