Skip to main content

Report Designer Server-Side Configuration (ASP.NET Core)

  • 9 minutes to read

This document describes how to create and configure an ASP.NET Core application as a server-side solution to use the End-User Web Report Designer in JavaScript. You can use the DevExpress or Microsoft template to create an application.

Use DevExpress Templates

Use the DevExpress ASP.NET Core Reporting Backend template to create a server-side application for the Report Designer. The back-end application defines a pre-built tabular report bound to sample data (SQL, Object, or JSON).

Follow the steps below:

  1. Install DevExpress ASP.NET Core project templates from nuget.org:

    dotnet new install DevExpress.AspNetCore.ProjectTemplates
    
  2. To create an application from the template, run the following command in the terminal:

    dotnet new dx.aspnetcore.reporting.backend -n ServerApp
    
  3. Enable cross-origin requests (CORS). Specify the policy that allows any local application to access the report’s back-end. Use the SetIsOriginAllowed method to set it up.

    Call the UseCors method and pass the policy name as a parameter. The UseCors method should be called after the UseRouting method and before any MVC-related code. Place the UseCors method before the UseMvc or UseEndpoints methods.

    Open the application startup file and insert the following code:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddCors(options => {
        options.AddPolicy("AllowCorsPolicy", builder => {
            // Allow all ports on local host.
            builder.SetIsOriginAllowed(origin => new Uri(origin).Host == "localhost");
            builder.AllowAnyHeader();
            builder.AllowAnyMethod();
        });
    });
    
    var app = builder.Build();
    
    app.UseRouting();
    app.UseCors("AllowCorsPolicy");
    
    app.UseEndpoints(endpoints => {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
    
    app.Run();
    

This template is also available in the DevExpress Template Kit. For additional information on the DevExpress Template Kit, refer to the following topic: Cross-IDE Template Kit (Windows, macOS).

Template Options
CLI Option Template Kit Option Description
--framework <TFM> Target Framework Specifies the target framework. It expects a target framework moniker (TFM). Example: net8.0.
-ad, --add-designer Add Designer Page Specifies whether to add services required for the Report Designer.
The default value is true.
-ads, --add-data-source Add SQL Data Connection to the Data Source Wizard Specifies whether to create a sample connection string and register it in the Report Designer to create SQL Data Sources in the Report Wizard and Data Source Wizard. The connection string is also used to register a predefined data source.
The default value is true.
-ajs, --add-json-data-connection-storage Add Sample JSON Data Connection Storage Specifies whether to create a storage and register it to create JSON Data Sources in the Report Wizard and Data Source Wizard.
The default value is true.
-ao, --add-data-object Add Data Type to Object Data Source Wizard Specifies whether to add a sample data object to an application and register this data object to create Object Data Sources in the Report Wizard and Data Source Wizard.
The default value is false.
-dfb, --Dockerfile <None\|Debian\|...> Enable Docker Support for Selected OS Creates a Dockerfile based on the selected OS. Review the following online example for additional information: How to Use the SkiaSharp-Based DevExpress Drawing Engine. Select None to skip Docker support.
- None (default) - Skip docker support.
- Debian - Debian-based Dockerfile.
- Alpine - Alpine-based Dockerfile.
- Ubuntu - Ubuntu-based Dockerfile.
- openSUSE - openSUSE-based Dockerfile.
- Amazon Linux - Amazon Linux-based Dockerfile.
-D, --DocumentStorage <InMemory\|XPO\|...> Specify Document Cache Storage Type Specifies the storage type to cache documents that the report creates. For more information, review the following help topic: Web Document Viewer Cache Management.
- InMemoryStorage (default) - Default cache that stores objects directly in memory without serialization, optimized for frequent operations.
- XPOStorage - Implements a database cache based on the XPO library, designed for multi-instance applications to prevent cache data loss.
- FileStorage - Configures the reporting engine to store documents generated by reports on disk instead of in memory.
- DistributedCache - Configures the cache as an external service that uses an ASP.NET Core distributed caching mechanism and can be shared by multiple application servers.
- AzureStorage - Configures the application to use Azure caching services.
-mcp, --use-devexpress-mcp Use DevExpress MCP Installs the DevExpress Documentation MCP Server for the generated solution. GitHub Copilot queries DevExpress documentation through this server to improve response accuracy and reduce model hallucinations. Refer to DevExpress Documentation MCP Server for setup details.
-prerelease, --use-prerelease-dx-version A flag that indicates whether to use a pre-release DevExpress package version in the project.
--dx-version <version> Specifies DevExpress package version to be used in the project. Examples: 25.2.3, 25.2.*, 25.2.*-*
--dx-nuget-feed <feed> Specifies the NuGet Feed URL. Refer to nuget.devexpress.com to obtain your personal feed URL (available for registered users).

Use Microsoft Visual Studio Template

You can create an ASP.NET Core application based on the built-in Visual Studio template and configure it for the DevExpress Report Designer as follows:

  1. Create a new ASP.NET Core Web Application (or open an existing application).

    Create a new project

  2. Configure a new project.

    Configure a new project

  3. Specify additional information.

    Specify Additional information

  4. Right-click the Dependencies node in the Solution Explorer and select Manage NuGet Packages in the invoked context menu.

    Manage NuGet Packages

  5. Select DevExpress 25.2 Local in the Package source drop-down list and go to the Browse page. Find the DevExpress.AspNetCore.Reporting package v25.2.6 and install it:

  6. Open the Program.cs file and modify it to configure services as demonstrated below.

    using DevExpress.AspNetCore;
    //...
    
    var builder = WebApplication.CreateBuilder(args);
    
    // Register reporting services in an application's dependency injection container.
    builder.Services.AddDevExpressControls();
    // Use the AddMvcCore (or AddMvc) method to add MVC services.
    builder.Services.AddMvc(); 
    
    builder.Services.ConfigureReportingServices(configurator => {
        if(builder.Environment.IsDevelopment()) {
            configurator.UseDevelopmentMode();
        }
        configurator.ConfigureReportDesigner(designerConfigurator => {
        });
        configurator.ConfigureWebDocumentViewer(viewerConfigurator => {
            // Use cache for document generation and export.
            // This setting is necessary in asynchronous mode and when a report has interactive or drill down features.
            viewerConfigurator.UseCachedReportSourceBuilder();
        });
    });
    //...
    
    var app = builder.Build();
    // ...
    // Initialize reporting services.
    app.UseDevExpressControls();
    // ...
    
  7. Create the Reports folder and add a report to the application. Use the Save command in the Visual Studio Report Designer smart tag to save the created report to a file in Report Xml (.repx) format in the Reports folder.

  8. Add a server-side report storage. To implement a report storage, add a new class inherited from the ReportStorageWebExtension class as described in the ReportStorageWebExtension help topic. Refer to the following help topic for more information and report storage examples: Add a Report Storage (ASP.NET Core).

  9. Register the report storage implemented in the previous step as a scoped service. Open the Program.cs file and add the following code :

    using DevExpress.XtraReports.Web.Extensions;
    //...
    builder.Services.AddScoped<ReportStorageWebExtension, CustomReportStorageWebExtension>();
    //...
    

Use CORS Policy

Enable cross-origin requests (CORS). Specify the policy that allows any local application to access the report’s back-end. Use the SetIsOriginAllowed method to set it up.

Call the UseCors method and pass the policy name as a parameter. The UseCors method should be called after the UseRouting method and before any MVC-related code. Place the UseCors method before the UseMvc or UseEndpoints methods.

Open the application startup file and insert the following code:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options => {
    options.AddPolicy("AllowCorsPolicy", builder => {
        // Allow all ports on local host.
        builder.SetIsOriginAllowed(origin => new Uri(origin).Host == "localhost");
        builder.AllowAnyHeader();
        builder.AllowAnyMethod();
    });
});

var app = builder.Build();

app.UseRouting();
app.UseCors("AllowCorsPolicy");

app.UseEndpoints(endpoints => {
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

app.Run();

Add Controllers

To implement custom controllers, inherit from the base controller class and specify a custom route.

The following table lists base controller classes that process requests from reporting components, default routes, and methods that allow you to specify custom routes:

Component Base Controller Class Predefined Route Custom Route
Report Designer ReportDesignerController DXXRD ReportDesignerHandlerUri(String)
Document Viewer WebDocumentViewerController DXXRDV ReportPreviewHandlerUri(String)
Query Builder QueryBuilderController DXXQB QueryBuilderHandlerUri(String)

An application with End-User Report Designer requires all three controllers for proper operation.

The following code snippet implements controllers for the web report designer:

using DevExpress.DataAccess.Sql;
using System.Collections.Generic;
using DevExpress.AspNetCore.Reporting.QueryBuilder;
using DevExpress.AspNetCore.Reporting.ReportDesigner;
using DevExpress.AspNetCore.Reporting.ReportDesigner.Native.Services;
using DevExpress.AspNetCore.Reporting.QueryBuilder.Native.Services;
using DevExpress.XtraReports.Web.ReportDesigner;
using DevExpress.XtraReports.Web.ReportDesigner.Services;
using DevExpress.AspNetCore.Reporting.WebDocumentViewer;
using DevExpress.AspNetCore.Reporting.WebDocumentViewer.Native.Services;
using Microsoft.AspNetCore.Mvc;

namespace ServerApp.Controllers {
    public class CustomWebDocumentViewerController : WebDocumentViewerController {
        public CustomWebDocumentViewerController(IWebDocumentViewerMvcControllerService controllerService) : base(controllerService) {
        }
    }
    public class CustomReportDesignerController : ReportDesignerController {
        public CustomReportDesignerController(IReportDesignerMvcControllerService controllerService) : base(controllerService) {
        }

        [HttpPost("[action]")]
        public IActionResult GetDesignerModel(
            [FromForm]string reportUrl, 
            [FromServices] IReportDesignerModelBuilder designerModelBuilder, 
            [FromForm] ReportDesignerSettingsBase designerModelSettings) {
            // ...
            var designerModel = designerModelBuilder.Report(reportUrl)
            // ...
                .BuildModel();
           designerModel.Assign(designerModelSettings);
           return DesignerModel(designerModel);
        }
    }

    public class CustomQueryBuilderController : QueryBuilderController {
        public CustomQueryBuilderController(IQueryBuilderMvcControllerService controllerService) : base(controllerService) {
        }
    }
}

This implementation overrides the GetDesignerModel method in the CustomReportDesignerController class. However, the default ReportDesignerController has a DXXRD predefined path. Set the getDesignerModelAction property to the DXXRD/GetDesignerModel path on the client.

The following code snippet specifies the getDesignerModelAction property in an Angular application:

export class AppComponent {
    title = 'DXReportDesignerSample';
    getDesignerModelAction = "DXXRD/GetDesignerModel";
    reportUrl = "TestReport?testId";
    hostUrl = 'https://localhost:5001/';
}

For more code samples with custom controllers, review the following example:

View Example: ASP.NET Core Reporting - Best Practices

Add Data Sources

To add data sources so that they become available for users in the Report Designer, modify the GetDesignerModel method as follows:

using DevExpress.DataAccess.Sql;
using System.Collections.Generic;
using DevExpress.AspNetCore.Reporting.QueryBuilder;
using DevExpress.AspNetCore.Reporting.ReportDesigner;
using DevExpress.AspNetCore.Reporting.ReportDesigner.Native.Services;
using DevExpress.AspNetCore.Reporting.QueryBuilder.Native.Services;
using DevExpress.XtraReports.Web.ClientControls;
using DevExpress.XtraReports.Web.ReportDesigner;
using DevExpress.XtraReports.Web.ReportDesigner.Services;
using DevExpress.AspNetCore.Reporting.WebDocumentViewer;
using DevExpress.AspNetCore.Reporting.WebDocumentViewer.Native.Services;
using Microsoft.AspNetCore.Mvc;

namespace ServerApp.Controllers {
    public class CustomWebDocumentViewerController : WebDocumentViewerController {
        public CustomWebDocumentViewerController(IWebDocumentViewerMvcControllerService controllerService) : base(controllerService) {
        }
    }
    public class CustomReportDesignerController : ReportDesignerController {
        public CustomReportDesignerController(IReportDesignerMvcControllerService controllerService) : base(controllerService) {
        }

        [HttpPost("[action]")]
        public IActionResult GetDesignerModel([FromForm]string reportUrl, [FromServices] IReportDesignerModelBuilder designerModelBuilder, [FromForm] ReportDesignerSettingsBase designerModelSettings) {
            var ds = new SqlDataSource("NWindConnectionString");

            // Create a SQL query to access the Products data table.
            SelectQuery query = SelectQueryFluentBuilder.AddTable("Products").SelectAllColumnsFromTable().Build("Products");
            ds.Queries.Add(query);
            ds.RebuildResultSchema();

            var designerModel = designerModelBuilder.Report(reportUrl)
                .DataSources(dataSources => {
                    dataSources.Add("Northwind", ds);
                })
                .BuildModel();
           designerModel.Assign(designerModelSettings);
           var clientSideModelSettings = new ClientSideModelSettings {
                IncludeLocalization = false,
                IncludeCldrData = false,
                IncludeCldrSupplemental = false
           };
           return DesignerModel(designerModel, clientSideModelSettings);
        }
    }

    public class CustomQueryBuilderController : QueryBuilderController {
        public CustomQueryBuilderController(IQueryBuilderMvcControllerService controllerService) : base(controllerService) {
        }
    }
}

Create the NorthWind sample database on the local SQL Server and add the following element to the appsettings.json file:

"ConnectionStrings": {
"NWindConnectionString": "XpoProvider=MSSqlServer;data source=localhost;integrated security=SSPI;initial catalog=Northwind"
}

Determine the Host URL

The URL and port number are required for the host setting when you configure the client application as described in the following help topics:

If you do not use Visual Studio to run the project, inspect the launchSettings.json file for the applicationUrl setting. If your application uses HTTPS redirection and calls the UseHttpsRedirection method at startup, the port number is specified in the sslPort setting.

See Also