All docs
V20.2
20.2
20.1
The page you are viewing does not exist in version 20.1. This link will take you to the root page.
19.2
The page you are viewing does not exist in version 19.2. This link will take you to the root page.
19.1
The page you are viewing does not exist in version 19.1. This link will take you to the root page.
18.2
The page you are viewing does not exist in version 18.2. This link will take you to the root page.
18.1
The page you are viewing does not exist in version 18.1. This link will take you to the root page.
17.2
The page you are viewing does not exist in version 17.2. This link will take you to the root page.

IReportProviderAsync Interface

Allows you to implement a service that asynchronously resolves a report unique name (report URL) to a report instance.

Namespace: DevExpress.XtraReports.Services

Assembly: DevExpress.XtraReports.v20.2.dll

Declaration

public interface IReportProviderAsync
Public Interface IReportProviderAsync

Remarks

You can create a custom service that implements the IReportProviderAsync interface to resolve a string to a report instance.

The GetModelAsync methods call this service to get a report by its unique name (also referred to as the report URL). When a report contains subreports, the service is used to resolve subreport unique names.

A custom IReportProviderAsync service has priority over the custom ReportStorageWebExtension service. If your application includes the Web Document Viewer and a custom IWebDocumentViewerReportResolver service, then that service resolves report URLs instead of the IReportProviderAsync.

NOTE

ASP.NET Core Razor Helpers cannot use asynchronous API if the Bind method receives a report instance or a string (report unique name) as a parameter. Thus, the OpenReport method does not run asynchronously after the UseAsyncEngine method is called.

In your project, you must bind report controls to the WebDocumentViewerModel or ReportDesignerModel objects originated from controllers. The controller-based models allow you to use asynchronous API and avoid obscure errors that may occur when a subreport fails to load and throws an exception, or when an attempt to refresh a list of predefined dynamic parameter values fails.

A controller must call the WebDocumentViewerClientSideModelGenerator.GetModelAsync or ReportDesignerClientSideModelGenerator.GetModelAsync methods to generate report models and send them to the Document Viewer and End User Report Designer.

Implementation

NOTE

The complete sample project is available in the following DevExpress Examples repository on GitHub: How to Use the Asynchronous Engine for Web Reporting.

Add custom logic to the GetReportAsync method. The method instantiates and returns a report based on the specified report unique name. The following code is the IReportProviderAsync implementation that retrieves a serialized report from the report storage:

using System.IO;
using System.Threading.Tasks;
using DevExpress.XtraReports.Services;
using DevExpress.XtraReports.UI;
using DevExpress.XtraReports.Web.Extensions;

// ...
    public class CustomReportProviderAsync : IReportProviderAsync
    {
        readonly ReportStorageWebExtension reportStorageWebExtension;

        public CustomReportProviderAsync(ReportStorageWebExtension reportStorageWebExtension)
        {
            this.reportStorageWebExtension = reportStorageWebExtension;
        }
        public async Task<XtraReport> GetReportAsync(string id, ReportProviderContext context)
        {
            var reportLayout = await reportStorageWebExtension.GetDataAsync(id);
            if (reportLayout == null)
                return null;
            using (var ms = new MemoryStream(reportLayout))
            {
                var report = XtraReport.FromXmlStream(ms);
                return report;
            }
        }
    }

Registration

  • ASP.NET Web Forms and ASP.NET MVC

    Call the following methods at application startup:

    using DevExpress.XtraReports.Services;
    // ...
      void Application_Start() {
        // ...
        DevExpress.XtraReports.Web.ReportDesigner.DefaultReportDesignerContainer.Register<IReportProviderAsync, CustomReportProviderAsync>();
        DevExpress.XtraReports.Web.WebDocumentViewer.DefaultWebDocumentViewerContainer.Register<IReportProviderAsync, CustomReportProviderAsync>();
        //...
        DevExpress.XtraReports.Web.ReportDesigner.DefaultReportDesignerContainer.UseAsyncEngine();
        DevExpress.XtraReports.Web.WebDocumentViewer.DefaultWebDocumentViewerContainer.UseAsyncEngine();
      }
    
  • ASP.NET Core

    Call the AddScoped method at application startup to register the service and use the ReportingConfigurationBuilder.UseAsyncEngine method to enable asynchronous mode:

    using Microsoft.Extensions.DependencyInjection;
    using DevExpress.XtraReports.Services;
    
      public class Startup {
      // ...
          public void ConfigureServices(IServiceCollection services) {
              // ...
              services.AddScoped<IReportProviderAsync, CustomReportProviderAsync>();
              // ...
              services.ConfigureReportingServices(configurator => {
                  // ...
                  configurator.UseAsyncEngine();
              });
          }
          // ...
      }
    

Usage Example

The following code is a controller action method that handles incoming browser requests. It uses a custom IReportProviderAsync service to obtain a subreport when a report is exported to PDF.

using DevExpress.XtraReports.Services;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.Design;
using System.IO;
using System.Threading.Tasks;
// ...
    public class HomeController : Controller
    {
      // ...
      public async Task<IActionResult> ExportToPdf([FromServices] IReportProviderAsync reportProviderAsync, [FromQuery] string reportName = "RootReport")
        {
          var report = await reportProviderAsync.GetReportAsync(reportName, null);
          var reportServiceContainer = (IServiceContainer)report;
          reportServiceContainer.RemoveService(typeof(IReportProviderAsync));
          reportServiceContainer.AddService(typeof(IReportProviderAsync), reportProviderAsync);
          using (var stream = new MemoryStream()) {
              await report.CreateDocumentAsync();
              await report.ExportToPdfAsync(stream);
              return File(stream.ToArray(), System.Net.Mime.MediaTypeNames.Application.Pdf);
          }
        }
See Also