Skip to main content
All docs
V22.1

IReportProviderAsync Interface

Allows you to implement a service that asynchronously resolves a report name to a report instance.

Namespace: DevExpress.XtraReports.Services

Assembly: DevExpress.XtraReports.v22.1.dll

Declaration

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 with the names specified by the XRSubreport.ReportSourceUrl property, the IReportProvider service is used to resolve subreport names.

A custom IReportProviderAsync service has priority over the custom ReportStorageWebExtension service.

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);
          }
        }

Note

Review the Open a Report in ASP.NET Core Application help topic for more information.

See Also