Skip to main content
A newer version of this page is available. .

Add an End-User Report Designer to an ASP.NET Core Application

  • 6 minutes to read

This document describes how to add the Report Designer control to an ASP.NET Core application.

Note

The complete sample project How to Add an End-User Report Designer to an ASP.NET Core Application is available in the DevExpress Examples repository.

Prerequisites

Your ASP.NET Core Application should have the Reports folder with a sample report named XtraReport. Review the ASP.NET Core Reporting Overview article and Create a Report in Visual Studio tutorial for information about how to add a report to your application.

Install Packages

Perform the following steps to install the NuGet packages:

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

    context-menu-manage-nuget-packages

  2. Select DevExpress 19.2 Local in the Package source drop-down list, go to the Browse page, and install the DevExpress.AspNetCore.Reporting package.

    install-asp-net-core-reporting-nuget-package

  3. Right-click the project in the Solution Explorer and select Add | Add New Item. In the invoked Add New Item dialog, select the Installed | Visual C# | ASP.NET Core | Web category and the npm Configuration File item template. Click Add.

    add-npm-config-file

    This adds the package.json file to the project. Open this file and add the following dependencies:

    {
        "version": "1.0.0",
        "name": "asp.net",
        "private": true,
        "dependencies": {
            "bootstrap": "^3.3.7",
            "cldrjs": "^0.5.0",
            "devextreme": "~19.2.15",
            "@devexpress/analytics-core": "~19.2.15",
            "devexpress-reporting": "~19.2.15",
            "devexpress-richedit": "~19.2.15",
            "globalize": "^1.3.0",
            "jquery-ui-dist": "^1.12.1",
            "ace-builds": "^1.3.3"
        }
    }
    

    Tip

    You can reduce the size of the redistributables and exclude the devexpress-richedit package and scripts required for inline rich text editing in the XRRichText control.

  4. Right-click the package.json file and select Restore Packages. This adds the node_modules folder to the application project.

  5. Open the Startup.cs file and modify the Configure method of the Startup class to call the app.UseStaticFiles method with the parameter as illustrated in the following code snippet:

    using DevExpress.AspNetCore;
    using DevExpress.AspNetCore.Reporting;
    using Microsoft.Extensions.FileProviders;
    using System.IO;
    //...
    
    public class Startup {
    //...
        public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
            // ...
            app.UseStaticFiles(new StaticFileOptions {
                FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "node_modules")),
                RequestPath = "/node_modules"
            });         
        }
    }
    

    Note

    The client can access all the files in the node_modules folder. To restrict access, use bundling and minification with the Grunt.

Implement Report Storage

Perform the following steps to implement server-side report storage for the Report Designer:

  1. Right-click the project in the Solution Explorer and select Add | New Folder. Name the folder Services.

  2. Add a new MyReportStorageWebExtension class inherited from the abstract ReportStorageWebExtension class and implement the following methods:

    Method Description
    ReportStorageWebExtension.IsValidUrl(String) Determines whether or not the specified URL is valid for the current report storage.
    ReportStorageWebExtension.CanSetData(String) Determines whether or not storing a report in a report storage using the specified URL is allowed.
    ReportStorageWebExtension.SetData(XtraReport, String) Stores the specified report to a Report Storage using the specified URL (i.e, saves existing reports only).
    ReportStorageWebExtension.SetNewData(XtraReport, String) Stores the specified report using a new URL (i.e., saves new reports only).
    ReportStorageWebExtension.GetData(String) Returns report layout data stored in a Report Storage using the specified URL.
    ReportStorageWebExtension.GetUrls() Returns a dictionary of the existing report URLs and display names.
    using DevExpress.XtraReports.UI;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.ServiceModel;
    
    namespace EndUserDesignerExample
    {
        public class MyReportStorageWebExtension : DevExpress.XtraReports.Web.Extensions.ReportStorageWebExtension
        {
            readonly string reportDirectory;
            const string FileExtension = ".repx";
            public MyReportStorageWebExtension(string reportDirectory){
                this.reportDirectory = reportDirectory;
            }
    
            public override bool CanSetData(string url){
                return true;
            }
    
            public override bool IsValidUrl(string url){
                return true;
            }
    
            public override byte[] GetData(string url){
                try
                {
                    using (var reportFile = File.Open(Path.Combine(reportDirectory, url + FileExtension), FileMode.Open))
                    using (var memoryStream = new MemoryStream())
                    {
                        reportFile.CopyTo(memoryStream);
                        return memoryStream.ToArray();
                    }
                }
                catch (Exception)
                {
                    throw new FaultException(new FaultReason(string.Format("Cannot not find the report '{0}'.", url)), new FaultCode("Server"), "GetData");
                }
            }
    
            public override Dictionary<string, string> GetUrls(){
                return Directory.GetFiles(reportDirectory, "*" + FileExtension)
                                        .Select(Path.GetFileNameWithoutExtension)
                                        .ToDictionary<string, string>(x => x);
            }
    
            public override void SetData(XtraReport report, string url){
                using (var reportFile = File.Open(Path.Combine(reportDirectory, url + FileExtension), FileMode.OpenOrCreate))
                {
                    report.SaveLayoutToXml(reportFile);
                }
            }
    
            public override string SetNewData(XtraReport report, string defaultUrl){
                SetData(report, defaultUrl);
                return defaultUrl;
            }
        }
    }
    
  3. Use the static ReportStorageWebExtension.RegisterExtensionGlobal method at the application startup to register a custom report storage. Open the Startup file and add the following code to the Configure method of the Startup class:

    using DevExpress.AspNetCore;
    using DevExpress.AspNetCore.Reporting;
    //... 
    
    public class Startup {
        //... 
            public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
        // ...
            string reportDirectory = System.IO.Path.Combine(env.ContentRootPath, "Reports");
            DevExpress.XtraReports.Web.Extensions.ReportStorageWebExtension.RegisterExtensionGlobal(new MyReportStorageWebExtension(reportDirectory));   
    }
    //...    
    }
    

    Note

    Reports is the name of the folder where the reports are located.

    Refer to the Implement a Report Storage topic for more information and a report storage example.

Add the Report Designer Control

Perform the following steps to integrate the Report Designer into the ASP.NET Core project:

  1. Open the Startup file. Add the using DevExpress.AspNetCore namespace directive to enable the AddDevExpressControls and UseDevExpressControls extension methods. Add the following code to the ConfigureServices and Configure methods of the Startup class:

    using DevExpress.AspNetCore;
    //...
    
    public class Startup {
    //...
        public void ConfigureServices(IServiceCollection services) {
            // Register reporting services in an application's dependency injection container.
            services.AddDevExpressControls();
            // Add MVC services.
            services.AddMvc(); 
        }
    
        public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
            // ...
            // Initialize reporting services.
            app.UseDevExpressControls();
            // ...
        }
    }
    
  2. Add the DevExpress.AspNetCore namespace directive to the _ViewImports.cshtml file. Alternatively, you can add this namespace only to the views that contain Report Designer and Viewer controls.

    @using DevExpress.AspNetCore
    
  3. In the View file (the default view file is the Index.cshtml file), add the following code that uses the ReportDesigner wrapper to display the End-User Report Designer on the web page.

    @{
        ViewData["Title"] = "Home Page";
        @Html.DevExpress().ReportDesigner("ReportDesigner").Height("1000px").Bind("Report1")
    }
    
  4. Add a stylesheet and script references to the page (Index.cshtml in this example) that displays the End-User Report Designer control :

    <link href="~/node_modules/jquery-ui-dist/jquery-ui.min.css" rel="stylesheet" />
    <link href="~/node_modules/devextreme/dist/css/dx.common.css" rel="stylesheet" />
    <link href="~/node_modules/devextreme/dist/css/dx.light.css" rel="stylesheet" />
    <link href="~/node_modules/@@devexpress/analytics-core/dist/css/dx-analytics.common.css" rel="stylesheet" />
    <link href="~/node_modules/@@devexpress/analytics-core/dist/css/dx-analytics.light.css" rel="stylesheet" />
    <link href="~/node_modules/@@devexpress/analytics-core/dist/css/dx-querybuilder.css" rel="stylesheet" />
    <link href="~/node_modules/devexpress-reporting/dist/css/dx-reportdesigner.css" rel="stylesheet" />
    <link href="~/node_modules/devexpress-reporting/dist/css/dx-webdocumentviewer.css" rel="stylesheet" />
    
    <!--Rich Text Editor support-->
    <link href="~/node_modules/devexpress-richedit/dist/dx.richedit.css" rel="stylesheet" />
    
    <!-- 3rd-party dependencies -->
    <script src="~/node_modules/jquery/dist/jquery.js"></script>
    <script src="~/node_modules/jquery-ui-dist/jquery-ui.js"></script>
    <script src="~/node_modules/knockout/build/output/knockout-latest.js"></script>
    <script src="~/node_modules/ace-builds/src-min-noconflict/ace.js"></script>
    <script src="~/node_modules/ace-builds/src-min-noconflict/ext-language_tools.js"></script>
    <script src="~/node_modules/ace-builds/src-min-noconflict/theme-dreamweaver.js"></script>
    <script src="~/node_modules/ace-builds/src-min-noconflict/theme-ambiance.js"></script>
    <script src="~/node_modules/ace-builds/src-min-noconflict/snippets/text.js"></script>
    <script src="~/node_modules/cldrjs/dist/cldr.js"></script>
    <script src="~/node_modules/cldrjs/dist/cldr/event.js"></script>
    <script src="~/node_modules/cldrjs/dist/cldr/supplemental.js"></script>
    <script src="~/node_modules/cldrjs/dist/cldr/unresolved.js"></script>
    <script src="~/node_modules/globalize/dist/globalize.js"></script>
    <script src="~/node_modules/globalize/dist/globalize/message.js"></script>
    <script src="~/node_modules/globalize/dist/globalize/number.js"></script>
    <script src="~/node_modules/globalize/dist/globalize/currency.js"></script>
    <script src="~/node_modules/globalize/dist/globalize/date.js"></script>
    
    
    <script src="~/node_modules/devextreme/dist/js/dx.all.js"></script>
    
    <!--Rich Text Editor support-->
    <script src="~/node_modules/jszip/dist/jszip.min.js"></script>
    <script src="~/node_modules/devexpress-richedit/dist/dx.richedit.min.js"></script>
    <!-- -->
    
    <script src="~/node_modules/@@devexpress/analytics-core/dist/js/dx-analytics-core.min.js"></script>
    <script src="~/node_modules/@@devexpress/analytics-core/dist/js/dx-querybuilder.min.js"></script>
    <script src="~/node_modules/devexpress-reporting/dist/js/dx-webdocumentviewer.min.js"></script>
    <script src="~/node_modules/devexpress-reporting/dist/js/dx-reportdesigner.min.js"></script>
    

    Important

    The order of the references is important. Ensure that all the references listed above are included in the page and each library is referenced only once.

    Note

    Review the Report Designer Requirements and Limitations topic for information on the requirements for deploying the control on the client.

Next Steps