Microsoft Azure Reporting

  • 9 minutes to read

This document describes how to run reporting applications in the Microsoft Azure environment.

Prerequisites

ASP.NET MVC and Web Forms

Before you run web reporting controls on Azure, install packages in one of the following ways:

ASP.NET Core

Before running web reporting controls on Azure, install the DevExpress.AspNetCore.Reporting.Azure NuGet package that provides services for web reporting applications in the Microsoft Azure environment. Review the Install DevExpress Controls Using NuGet Packages section for more information.

Hosting Specifics

Single Hosting Instance

This option applies to the following hosting service configurations:

Reporting controls (Document Viewer and Report Designer's built-in Document Viewer) can switch to the mode that is compatible with the Azure environment. For this, do one of the following:

  • Azure Environment

    Call the following methods (depending on the target framework) at the 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
    ASP.NET MVC and Web Forms
    using DevExpress.XtraReports.Web.Azure.WebDocumentViewer;
    // ...
    protected void Application_Start(object sender, System.EventArgs e) {
      //...   
          AzureWebDocumentViewerContainer.UseAzureEnvironment(cloudStorageConnectionString);
    }
    
    ASP.NET Core
    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. This also affects the Web Report Designer because it uses the Web Document Viewer to display a document preview.

    If you use Report Designer in ASP.NET MVC or ASP.NET Web Forms application, yoo can also call the AzureReportDesignerContainer.UseAzureEnvironment method at the 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.

    ASP.NET MVC and Web Forms
    using DevExpress.XtraReports.Web.Azure.ReportDesigner;
    // ...
    
    protected void Application_Start(object sender, System.EventArgs e) {
       AzureReportDesignerContainer.UseAzureEnvironment(cloudStorageConnectionString);
    }
    
  • Cached Report Source Builder

    Cached Report Source Builder is an advanced alternative to the UseAzureEnvironment method. If you experience problems with document generation on Azure, call the following methods instead of the UseAzureEnvironment method:

    Framework Method
    ASP.NET Web Forms and MVC AzureWebDocumentViewerContainer.UseCachedReportSourceBuilder
    ASP.NET Core AzureReportingConfigurator.UseAzureCachedReportSourceBuilder
    ASP.NET MVC and Web Forms
    using DevExpress.XtraReports.Web.Azure.WebDocumentViewer;
    // ...
    protected void Application_Start(object sender, System.EventArgs e) {
      //...   
          AzureWebDocumentViewerContainer.UseCachedReportSourceBuilder(cloudStorageConnectionString);
    }
    
    ASP.NET Core
    using DevExpress.AspNetCore.Reporting;
    using DevExpress.AspNetCore.Reporting.Azure;
    ...
    public void ConfigureServices(IServiceCollection services) {
    ...
      services.ConfigureReportingServices(configurator => {
          configurator.ConfigureWebDocumentViewer(viewerConfigurator => 
              {
                  viewerConfigurator.UseAzureCachedReportSourceBuilder(cloudStorageConnectionString);
              });
          });
      }
    

Multiple Hosting 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 (that is, 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 suitable for your deployment strategy. Exclude the Zone Redundant Storage (ZRS) option because it works only with blob containers while Web Document Viewer requires both tables and blobs.

To scale a web application on multiple instances, do one of the following:

  • 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 the following NuGet packages (depending 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

    If you start with prerequisites, the Service Bus packages are installed automatically.

    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 the application startup:

    Framework Method
    ASP.NET Web Forms and MVC AzureWebDocumentViewerContainer.UseAzureEnvironment
    ASP.NET Core AzureReportingConfigurator.UseAzureEnvironment
    ASP.NET Web Forms and MVC
    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();
    }
    
    ASP.NET Core
    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 Cached Report Source Builder

    If Service Bus is not available, call the following method instead of the UseAzureEnvironment method described in the previous section:

    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.

    ASP.NET MVC and Web Forms
    using DevExpress.XtraReports.Web.Azure.WebDocumentViewer;
    // ...
    protected void Application_Start(object sender, System.EventArgs e) {
      //...   
          AzureWebDocumentViewerContainer.UseCachedReportSourceBuilder(cloudStorageConnectionString, StorageSynchronizationMode.InterProcess);
    }
    
    ASP.NET Core
    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 Synchronous Document Creation

    A report generates a document asynchronously, and HttpContext.Session is not available in the report's event handlers.

    To address this issue, force synchronous document creation:

    1. Create a custom WebDocumentViewerOperationLogger implementation that overrides the BuildStarting method. The method's code should call the the XtraReport.CreateDocument method, as illustrated below:

      CustomLogger class
      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;
          }
          // ...
      }
      
    2. At the 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 the services are registered.

      ASP.NET Web Forms and MVC
      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();
      }
      
      ASP.NET Core
      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, 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 the 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 Azure environment serializes the report definitions to XML. The resulting REPX file is stored in a 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 (it happens 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 the Table Storage and saves document files in the 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 the "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

Image Rendering

All controls that can be rendered as a metafile or a bitmap are rendered as a bitmap. The XRChart, XRSparkline, XRGauge and WinControlContainer controls are rendered as a bitmap 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 Document Viewer Lifecycle topic.

See Also