Report Designer Server-Side Configuration (ASP.NET Core)
- 7 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 Visual Studio template to create an application.
Step 1: Create an ASP.NET Core Application
Use DevExpress Template or Microsoft Visual Studio Template to create a new project.
Use DevExpress Template (recommended)
You can use the Template Gallery to create a new ASP.NET Core project as follows:
Invoke the DevExpress Template Gallery, select Reporting Application under the .NET category and click Create Project.
In the Reporting Control Setting tab, enable the Add Designer Page and Add Report Storage check boxes and click Create Project.
(optionally) Open the ReportStorageWebExtension.cs file and customize the report storage implementation.
The template generates a sample storage (a ReportStorageWebExtension descendant) for demonstration purposes only. Create your own implementation for use in production.
For a detailed tutorial, refer to the following help topic: Create an ASP.NET Core Application with a Report Designer.
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:
Create a new ASP.NET Core Web Application (or open an existing application).
Configure a new project.
Specify additional information.
Right-click the Dependencies node in the Solution Explorer and select Manage NuGet Packages in the invoked context menu.
Select DevExpress 24.1 Local in the Package source drop-down list and go to the Browse page. Find the DevExpress.AspNetCore.Reporting package v24.1.7 and install it:
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(); // ...
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.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).
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>(); //...
Step 2: Configure the Application
Use CORS Policy
Enable cross-origin requests (CORS) in the newly created ASP.NET Core application. 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.AspNetCore.Reporting.QueryBuilder;
using DevExpress.AspNetCore.Reporting.QueryBuilder.Native.Services;
using DevExpress.AspNetCore.Reporting.ReportDesigner;
using DevExpress.AspNetCore.Reporting.ReportDesigner.Native.Services;
using DevExpress.AspNetCore.Reporting.WebDocumentViewer;
using DevExpress.AspNetCore.Reporting.WebDocumentViewer.Native.Services;
using DevExpress.DataAccess.Sql;
using DevExpress.XtraReports.Web.ReportDesigner.Services;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ServerSideAspNetCoreReportingApp.Controllers {
public class CustomReportDesignerController : ReportDesignerController {
public CustomReportDesignerController(IReportDesignerMvcControllerService controllerService) : base(controllerService) {
}
[HttpPost("[action]")]
public async Task<IActionResult> GetDesignerModel(
[FromForm] string reportName,
[FromServices] IReportDesignerModelBuilder reportDesignerModelBuilder) {
// ...
reportName = string.IsNullOrEmpty(reportName) ? "TestReport" : reportName;
var designerModel = await reportDesignerModelBuilder
.Report(reportName)
// ...
.BuildModelAsync();
return DesignerModel(designerModel);
}
}
public class CustomQueryBuilderController : QueryBuilderController {
public CustomQueryBuilderController(IQueryBuilderMvcControllerService controllerService) : base(controllerService) {
}
}
public class CustomWebDocumentViewerController : WebDocumentViewerController {
public CustomWebDocumentViewerController(IWebDocumentViewerMvcControllerService controllerService) : base(controllerService) {
}
}
}
This implementation overrides the GetDesignerModel
method in the CustomReportDesignerController
class. However, the default ReportDesignerController has a DXXRD predefined path. This means that on the client you should set the getDesignerModelAction
property to the DXXRD/GetDesignerModel
path.
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:
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.AspNetCore.Reporting.QueryBuilder;
using DevExpress.AspNetCore.Reporting.QueryBuilder.Native.Services;
using DevExpress.AspNetCore.Reporting.ReportDesigner;
using DevExpress.AspNetCore.Reporting.ReportDesigner.Native.Services;
using DevExpress.AspNetCore.Reporting.WebDocumentViewer;
using DevExpress.AspNetCore.Reporting.WebDocumentViewer.Native.Services;
using DevExpress.DataAccess.Sql;
using DevExpress.XtraReports.Web.ReportDesigner.Services;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ServerSideAspNetCoreReportingApp.Controllers {
public class CustomReportDesignerController : ReportDesignerController {
public CustomReportDesignerController(IReportDesignerMvcControllerService controllerService) : base(controllerService) {
}
[HttpPost("[action]")]
public async Task<IActionResult> GetDesignerModel(
[FromForm] string reportName,
[FromServices] IReportDesignerModelBuilder reportDesignerModelBuilder) {
var dataSources = new Dictionary<string, object>();
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();
dataSources.Add("Northwind", ds);
reportName = string.IsNullOrEmpty(reportName) ? "TestReport" : reportName;
var designerModel = await reportDesignerModelBuilder
.Report(reportName)
.DataSources(dataSources)
.BuildModelAsync();
return DesignerModel(designerModel);
}
}
public class CustomQueryBuilderController : QueryBuilderController {
public CustomQueryBuilderController(IQueryBuilderMvcControllerService controllerService) : base(controllerService) {
}
}
public class CustomWebDocumentViewerController : WebDocumentViewerController {
public CustomWebDocumentViewerController(IWebDocumentViewerMvcControllerService controllerService) : base(controllerService) {
}
}
}
If you started with the DevExpress template to create an application, the project already contains the SQLite database and the
NWindConnectionString
is a connection string for this database:"ConnectionStrings": { "NWindConnectionString": "XpoProvider=SQLite;Data Source=|DataDirectory|/Data/nwind.db", }
If you started with the Microsoft generic template, 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" }
Step 3: 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:
- Report Designer Integration in Angular
- Report Designer Integration in React
- Report Designer Integration in Vue
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.