Report Designer Server-Side Configuration (ASP.NET MVC)
- 6 minutes to read
This document describes how to create and configure an ASP.NET MVC application as a server-side solution to use the End-User Web Report Designer in JavaScript:
Note
The complete sample project is available in the following DevExpress Examples repository on GitHub: How to Perform the JavaScript Report Designer Integration (with npm or Yarn package managers).
Use the Template Gallery to create a new ASP.NET MVC project.
Note
To add reporting functionality to an existing MVC application, register the required extensions as described in the following help topic: How to Integrate ASP.NET MVC Reporting Extensions Into an Existing Project.
Create custom MVC controllers and inherit them from the following classes:
WebDocumentViewerApiControllerBase
using DevExpress.Web.Mvc.Controllers; using System.Web.Mvc; namespace DXWebApplication1.Controllers { public class WebDocumentViewerController : WebDocumentViewerApiControllerBase { // // GET: /WebDocumentViewer/ public override ActionResult Invoke() { var result = base.Invoke(); // Allow cross-domain requests. Response.AppendHeader("Access-Control-Allow-Origin", "*"); return result; } } }
ReportDesignerApiControllerBase
using DevExpress.DataAccess.Sql; using DevExpress.Web.Mvc.Controllers; using DevExpress.XtraReports.Web.ReportDesigner; using System.Collections.Generic; using System.Web.Mvc; namespace DXWebApplication1.Controllers { public class ReportDesignerController : ReportDesignerApiControllerBase { public override ActionResult Invoke() { var result = base.Invoke(); // Allow cross-domain requests. Response.AppendHeader("Access-Control-Allow-Origin", "*"); return result; } public ActionResult GetReportDesignerModel(string reportUrl) { Response.AppendHeader("Access-Control-Allow-Origin", "*"); string modelJsonScript = new ReportDesignerClientSideModelGenerator() .GetJsonModelScript( reportUrl, // The URL of a report that is opened in the Report Designer when the application starts. GetAvailableDataSources(), // Available data sources in the Report Designer that can be added to reports. "ReportDesigner/Invoke", // The URI path of the controller action that processes requests from the Report Designer. "WebDocumentViewer/Invoke",// The URI path of the controller action that processes requests from the Web Document Viewer. "QueryBuilder/Invoke" // The URI path of the controller action that processes requests from the Query Builder. ); return Content(modelJsonScript, "application/json"); } Dictionary<string, object> GetAvailableDataSources() { var dataSources = new Dictionary<string, object>(); SqlDataSource ds = new SqlDataSource("NWindConnectionString"); var query = SelectQueryFluentBuilder.AddTable("Products").SelectAllColumns().Build("Products"); ds.Queries.Add(query); ds.RebuildResultSchema(); dataSources.Add("SqlDataSource", ds); return dataSources; } } }
-
using DevExpress.Web.Mvc.Controllers; using System.Web.Mvc; namespace DXWebApplication1.Controllers { public class QueryBuilderController : QueryBuilderApiControllerBase { // // GET: /QueryBuilder/ public override ActionResult Invoke() { var result = base.Invoke(); // Allow cross-domain requests. Response.AppendHeader("Access-Control-Allow-Origin", "*"); return result; } } }
The Invoke action allows cross-domain requests:
using System.Web.Mvc; using DevExpress.Web.Mvc.Controllers; //... public class ReportDesignerController : ReportDesignerApiController { //... public override ActionResult Invoke() { var result = base.Invoke(); Response.AppendHeader("Access-Control-Allow-Origin", "*"); return result; } }
Tip
You can override the GetLocalization action to customize localization strings.
The project template contains the ReportStorageWebExtension class descendant that implements a server-side report storage.
Note
The template generates a sample storage (a ReportStorageWebExtension descendant) for demonstration purposes only. Create your own implementation for use in production.
using DevExpress.XtraReports.Web.Extensions; public class MyReportStorage : ReportStorageWebExtension { // ... }
At application startup, the static ReportStorageWebExtension.RegisterExtensionGlobal method registers the custom web report storage:
The ReportDesignerApiControllerBase implementation includes an action to create the Report Designer model. This action uses the ReportDesignerClientSideModelGenerator class and provides the following initialization data:
- A report URL (required);
- Available data sources (optional);
- URIs for reporting controllers’ Invoke actions (required).
using System.Web.Mvc; using DevExpress.Web.Mvc.Controllers; using DevExpress.XtraReports.Web.ReportDesigner; //... public class ReportDesignerController : ReportDesignerApiController { //... public ActionResult GetReportDesignerModel(string reportUrl) { Response.AppendHeader("Access-Control-Allow-Origin", "*"); string modelJsonScript = new ReportDesignerClientSideModelGenerator() .GetJsonModelScript( reportUrl, // The URL of a report that is opened in the Report Designer when the application starts. GetAvailableDataSources(), // Available data sources in the Report Designer that can be added to reports. "ReportDesigner/Invoke", // The URI path of the controller action that processes requests from the Report Designer. "WebDocumentViewer/Invoke",// The URI path of the controller action that processes requests from the Web Document Viewer. "QueryBuilder/Invoke" // The URI path of the controller action that processes requests from the Query Builder. ); return Content(modelJsonScript, "application/json"); } }
The GetAvailableDataSources method specified in the model settings above creates data sources for the Report Designer:
using System.Web.Mvc; using System.Collections.Generic; using DevExpress.Web.Mvc.Controllers; using DevExpress.DataAccess.Sql; public class ReportDesignerController : ReportDesignerApiController { // ... Dictionary<string, object> GetAvailableDataSources() { var dataSources = new Dictionary<string, object>(); SqlDataSource ds = new SqlDataSource("NWindConnectionString"); var query = SelectQueryFluentBuilder.AddTable("Products").SelectAllColumns().Build("Products"); ds.Queries.Add(query); ds.RebuildResultSchema(); dataSources.Add("SqlDataSource", ds); return dataSources; } }