Microsoft Azure Reporting
- 10 minutes to read
This document describes how to run reporting applications in the Microsoft Azure environment.
Prerequisites
Before you run web reporting controls on Azure, install packages in one of the following ways:
Install the DevExpress.Web.Reporting.Azure NuGet package that contains services for web reporting applications in the Microsoft Azure environment. Review the following help topic for more information: Install DevExpress Controls Using NuGet Packages.
Install the WindowsAzure.Storage version 6.1.0+ NuGet package and add a reference to the DevExpress.XtraReports.v20.1.Web.Azure.dll assembly to your project. Include the assembly in the deployment file list.
Before running web reporting controls on Azure, install the DevExpress.AspNetCore.Reporting.Azure NuGet package. It provides services for web reporting applications in the Microsoft Azure environment. Review the following help topic for more information: Install DevExpress Controls Using NuGet Packages.
Note
If your report contains the XRRichText control, set the AzureCompatibility.Enable property to true at application start. This setting is required so that the control renders correctly when the report is previewed, exported, or printed. If your report does not use the XRRichText control, set the property to false (default value).
Hosting Specifics
Hosting a Single Instance
This option applies to the following hosting service configurations:
- Azure Cloud Services or Web App (single instance)
- Azure Cloud Services or Web App (multiple instances with session affinity (ARR affinity) enabled)
Reporting controls (Document Viewer and Report Designer’s built-in Document Viewer) can switch to the mode that is compatible with the Azure environment. To switch to this mode, do one of the following:
Use Cached Report Source Builder
The Document Viewer component and the Report Designer component in Preview mode require access to the document while it is being generated.
Cached Report Source Builder forces reporting components to bind to the CachedReportSourceWeb instance instead of a simple report instance. CachedReportSourceWeb allows the application to store document pages in a persistent storage (Azure Cloud Storage) while the document is being generated. This is critical to prevent data loss when an application pool is reloaded.
Call the following methods to use the Cached Report Source Builder:
Framework Method ASP.NET Web Forms and MVC AzureWebDocumentViewerContainer.UseCachedReportSourceBuilder ASP.NET Core AzureReportingConfigurator.UseAzureCachedReportSourceBuilder using DevExpress.AspNetCore.Reporting; using DevExpress.AspNetCore.Reporting.Azure; ... public void ConfigureServices(IServiceCollection services) { ... services.ConfigureReportingServices(configurator => { configurator.ConfigureWebDocumentViewer(viewerConfigurator => { viewerConfigurator.UseAzureCachedReportSourceBuilder(cloudStorageConnectionString); }); }); }
UseAzureEnvironment Method
This method is used in v.19.2 and earlier, and it is still applicable. It replaces the Document Viewer and Report Designer internal services with services adjusted for Azure.
Call one of the following methods (based on the target framework) at application startup and specify the Azure Storage connection string as the method’s parameter:
Framework Method ASP.NET Web Forms and MVC AzureWebDocumentViewerContainer.UseAzureEnvironment ASP.NET Core AzureReportingConfigurator.UseAzureEnvironment using DevExpress.AspNetCore.Reporting; using DevExpress.AspNetCore.Reporting.Azure; ... public void ConfigureServices(IServiceCollection services) { ... services.ConfigureReportingServices(configurator => { configurator.ConfigureWebDocumentViewer(viewerConfigurator => { viewerConfigurator.UseAzureEnvironment(cloudStorageConnectionString); }); }); }
This method switches the Web Document Viewer’s internal services to services specifically designed for the decentralized Azure environment. The method also affects the Web Report Designer because the Designer’s preview uses the Web Document Viewer to display a document.
If you use the Report Designer in an ASP.NET MVC or ASP.NET Web Forms application, you can also call the AzureReportDesignerContainer.UseAzureEnvironment method at application startup and specify the Azure Storage connection string as the method’s parameter. The Web Report Designer encrypts the connection information sent to the client. The UseAzureEnvironment method instructs the Report Designer to store this information in Azure Table storage.
Hosting Multiple Instances
You can host the Web Document Viewer on multiple web application instances if you disable session affinity (ARR affinity).
Create an Azure Storage account to persist report definitions and documents in Azure storage (i.e., to enable the Document Viewer to preserve its state after an application restarts).
Select the Azure Storage account replication (LRS, ZRS, GRS, RA-GRS) that is most appropriate for your deployment strategy. Exclude the Zone Redundant Storage (ZRS) option because it only works with blob containers, and Web Document Viewer requires both tables and blobs.
To scale out a web application to multiple instances, do one of the following:
Use Cached Report Source Builder
The Document Viewer component and the Report Designer component in Preview mode require access to the document while it is being generated.
Cached Report Source Builder forces reporting components to bind to the CachedReportSourceWeb instance instead of a simple report instance. CachedReportSourceWeb allows the application to store document pages in a persistent storage (Azure Cloud Storage) while the document is being generated. This is critical to prevent data loss when the Load Balancer routes a request to an application instance where the document is not generated, or when an application pool is reloaded.
Tip
For more information on the document generation process, review the following help topic: Document Viewer Lifecycle.
To use the Cached Report Source Builder, call one of the following methods (based on the target framework):
Framework Method ASP.NET Web Forms and MVC AzureWebDocumentViewerContainer.UseCachedReportSourceBuilder ASP.NET Core AzureReportingConfigurator.UseAzureCachedReportSourceBuilder Note
Pass the StorageSynchronizationMode.InterProcess value as the second parameter to this method to enable inter-process synchronization.
using DevExpress.AspNetCore.Reporting; using DevExpress.AspNetCore.Reporting.Azure; using DevExpress.XtraReports.Web.WebDocumentViewer; ... public void ConfigureServices(IServiceCollection services) { ... services.ConfigureReportingServices(configurator => { configurator.ConfigureWebDocumentViewer(viewerConfigurator => { viewerConfigurator.UseAzureCachedReportSourceBuilder(cloudStorageConnectionString, StorageSynchronizationMode.InterProcess); }); }); }
Use Service Bus
Set up the Viewer for a Service Bus. A Service Bus tier should be Standard or Premium (because both Sessions and Topics are required).
The Service Bus requires one of the following NuGet packages (based on the target framework):
Framework Package ASP.NET Web Forms and MVC WindowsAzure.ServiceBus 2.7.0+ ASP.NET Core Microsoft.Azure.Management.ServiceBus 2.1.0+, Microsoft.Azure.ServiceBus 4.1.1+ Note
The Service Bus packages are installed automatically when you install the DevExpress Azure NuGet package.
To use a service bus, call the UseAzureEnvironment method with parameters that specify the Azure Storage connection string and a connection string to access the service bus at application startup:
Framework Method ASP.NET Web Forms and MVC AzureWebDocumentViewerContainer.UseAzureEnvironment ASP.NET Core AzureReportingConfigurator.UseAzureEnvironment using DevExpress.XtraReports.Web; using DevExpress.XtraReports.Web.Azure.WebDocumentViewer; // ... protected void Application_Start(object sender, System.EventArgs e) { AzureWebDocumentViewerContainer.UseAzureEnvironment(cloudStorageConnectionString, serviceBusConnectionString); ASPxWebDocumentViewer.StaticInitialize(); }
using DevExpress.AspNetCore.Reporting; using DevExpress.AspNetCore.Reporting.Azure; ... public void ConfigureServices(IServiceCollection services) { ... services.ConfigureReportingServices(configurator => { configurator.ConfigureWebDocumentViewer(viewerConfigurator => { viewerConfigurator.UseAzureEnvironment(cloudStorageConnectionString, serviceBusConnectionString); }); }); }
Note
If the target framework is ASP.NET Web Forms and MVC, call the ASPxWebDocumentViewer.StaticInitialize method after all other methods.
Use Synchronous Document Creation
If a report document is generated asynchronously (and HttpContext.Session is not available in the report’s event handlers), force synchronous document creation as follows:
Create a custom WebDocumentViewerOperationLogger implementation that overrides the BuildStarting method. The method’s code should call the the XtraReport.CreateDocument method, as illustrated below:
using DevExpress.XtraReports.UI; using DevExpress.XtraReports.Web.ReportDesigner; using DevExpress.XtraReports.Web.WebDocumentViewer; public class CustomLogger : WebDocumentViewerOperationLogger { public override Action BuildStarting(string reportId, string reportUrl, XtraReport report, ReportBuildProperties buildProperties) { report.CreateDocument(); return null; } // ... }
At application startup, call the UseAzureEnvironment method with the parameter that specifies the Azure Storage connection string and register the CustomLogger class implemented in the previous step.
Note
If the target framework is ASP.NET Web Forms and MVC, call the ASPxWebDocumentViewer.StaticInitialize method after all services are registered.
using DevExpress.XtraReports.Web; using DevExpress.XtraReports.Web.Azure.WebDocumentViewer; // ... protected void Application_Start(object sender, System.EventArgs e) { AzureWebDocumentViewerContainer.UseAzureEnvironment(cloudStorageConnectionString); DefaultWebDocumentViewerContainer.RegisterSingleton<WebDocumentViewerOperationLogger, CustomLogger>(); ASPxWebDocumentViewer.StaticInitialize(); }
using DevExpress.AspNetCore.Reporting; using DevExpress.AspNetCore.Reporting.Azure; using DevExpress.XtraReports.Web.WebDocumentViewer; //... public void ConfigureServices(IServiceCollection services) { //... services.AddDevExpressControls(); //... services.ConfigureReportingServices(configurator => { configurator.ConfigureWebDocumentViewer(viewerConfigurator => { viewerConfigurator.UseAzureEnvironment(cloudStorageConnectionString); }); }); services.AddTansient<WebDocumentViewerOperationLogger, CustomLogger>(); }
Tip
If the user changes report parameters, or performs drill-down or interactive sorting, the application should not pass the report instance to the Viewer’s OpenReport method. The report instance is not available on other machines that can handle corresponding HTTP requests. Instead, use another OpenReport overload that takes the URL as the parameter. To use a URL to load a report, register a report storage or create and register a class that implements the IWebDocumentViewerReportResolver interface.
Report Serialization
Web Document Viewer in an Azure environment serializes report definitions to XML. The REPX file that is generated is saved in Blob Storage.
A request that submits report parameter values or restores a drill-drown/drill-through/interactive sorting state requires a report instance in the following cases:
- If the Document Viewer’s request is routed to another server instance (when multiple server instances are used).
- When the Document Viewer’s request is routed to a single server instance, but the application pool is shut down due to inactivity.
A report instance is restored from an XML file and contains only settings that have been serialized (other settings are lost). You can use a custom WebDocumentViewerOperationLogger implementation to modify a report and apply settings.
Implement Custom Storages
Microsoft Azure is a distributed system, and virtual machines are shared between different clients. Information stored on a virtual machine can be lost when a Load Balancer turns this machine off and switches to a new machine.
To prevent information loss, the Web Document Viewer stores service information in Table Storage and saves document files in Blob Storage.
You can use a custom storage instead of Table and Blob storages. To do this, implement the following interfaces and substitute related services in a container:
Note
Web Document Viewer creates and uses “dxxrreports“ and “dxxrdocuments“ tables in Table Storage, and the “dxxrcommonstorage“ blob container in Blob Storage.
Limitations
PDF Fonts
The PDF export engine used in DevExpress Reporting relies on system GDI calls, some of which are not supported in Azure.
When a web app is hosted under the Free or Shared plan, the following limitations apply:
- right-to-left languages do not render correctly;
- only non-embedded fonts are supported.
Custom Fonts
- The PrivateFontCollection is not supported in Azure Web Apps.
Image Rendering
All controls that can be rendered as metafiles or bitmaps are rendered as bitmaps. The XRChart, XRSparkline, XRGauge and WinControlContainer controls are rendered as bitmaps despite their ImageType property value.
Important
3D charts are not supported in the Azure environment.
Caching Options
Azure Caching Settings
Applications that target ASP.NET Web Forms and MVC frameworks have the following default ‘Time to Live’ settings:
- Report: 2 minutes.
- Document: 1 minute.
Use the CacheCleanerSettings class to adjust the cache settings.
Document Viewer Lifecycle
For information about the mechanisms implemented in the Document Viewer, including the client-sever communication protocol and server-side report storage, review the following help topic: