How to show files rendered into Azure Blob Storage

I solved my initial problem on my own so I’m editing this ticket rather than starting a different one.

My company has a business need not to stage the rendered document on the local file system as the documents may contain PHI. What I’m trying to do is load the file from a stream from Azure blob storage, store the rendered document in Azure blob storage or just in memory, then present the rendered document to the user. I call AddAzureBlobStorage in Startup.cs with no problems, but the rendered documents do not appear in the configured store and I can’t find a good example of how to then display the rendered documents to the user.

@cbclark1983

There are two options here. Let’s say that there is a sample.docx file in your container:

Then you can enable a user to browse files in UI:

Or disable the file browser

builder.Services
        .AddGroupDocsViewerUI(config => {
            config.DisableFileBrowsing();
        });

and open a file by adding its name as a query string parameter ?file=sample.docx

The sample application that I was using: viewer-net-ui-azure-blob-storage.zip (7.2 KB)

Please let us know if it works for you.

Thanks for the response. The issue I’m still having is I’m not seeing the rendered version of the document added to the Azure blob storage. My code:

    using (Viewer viewer = new Viewer(stream))
    {
        ViewOptions viewOptions = HtmlViewOptions.ForEmbeddedResources("page_{0}.html");
        viewer.View(viewOptions);
    }

My understanding is that this code should result in the file contained in the stream being processed into a displayable format and then persisted in the configured data store, but that doesn’t seem to be happening. There must be configuration or a step I’m missing.

@cbclark1983

When running the code above the document passed as a stream variable will be processed and you’ll get page_1.html, page_2.html, and so on in the current directory and nothing more.

Please the following code:

using GroupDocs.Viewer;
using GroupDocs.Viewer.Logging;
using GroupDocs.Viewer.Options;

ViewerSettings settings = 
    new ViewerSettings(new ConsoleLogger());

Stream stream = GetFileStream();
using (Viewer viewer = new Viewer(stream, settings))
{
    ViewOptions viewOptions = HtmlViewOptions.ForEmbeddedResources("page_{0}.html");
    viewer.View(viewOptions);
}

Stream GetFileStream() => File.OpenRead("sample.docx");

When running this code the output directory will contain output HTML files. See
viewernet-sample.zip (326.7 KB).

To clarify the process the console output will be the following:

[TRACE] Rendering into HTML with embedded resources.
[TRACE] Detecting file type by extension.
[TRACE] File type detected successfully: Microsoft Word Open XML Document.
[TRACE] Opening document.
[TRACE] Document is loaded.
[TRACE] Applying options.
[TRACE] Converting page 1.
[TRACE] Page 1 conversion completed.
[TRACE] Converting page 2.
[TRACE] Page 2 conversion completed.
[TRACE] Releasing resources.

In case you need to store the output HTML files in any storage you can implement your custom stream provider

class MyPageStreamFactory : IPageStreamFactory
{
    public Stream CreatePageStream(int pageNumber) =>
        new MemoryStream();

    public void ReleasePageStream(int pageNumber, Stream pageStream)
    {
        //TODO: write page to a storage
        using (FileStream fs = File.Create($"page_{pageNumber}.html"))
        {
            pageStream.Position = 0;
            pageStream.CopyTo(fs);
        }

        pageStream.Dispose();
    }
}

Pass the instance of MyPageStreamFactory as a parameter of the factory method HtmlViewOptions.ForEmbeddedResources.

///...
using (Viewer viewer = new Viewer(stream, settings))
{
    ViewOptions viewOptions = 
        HtmlViewOptions.ForEmbeddedResources(new MyPageStreamFactory());
    viewer.View(viewOptions);
}

So even when you use .AddAzureBlobStorage() instead of .AddLocalStorage(), it will try to render the document to your local file system instead of using the configured Azure blob storage unless you implement a custom stream factory to upload the rendered file yourself?

Thanks, that’s the part that wasn’t clear to me, I would have intuitively expected AddAzureBlobStorage to handle both the writes and the reads.

@cbclark1983

That’s correct. The AddAzureBlobStorage is used to read the source files from storage. To write the output files you would need to implement IFileCache interface similar to InMemoryFileCache or LocalFileCache.