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

Create a Blazor Dashboard Application

  • 4 minutes to read

Important

Note that we do not have a native Dashboard UI component for Blazor. You can only integrate the client JavaScript Dashboard control into a Blazor application.

If you are not familiar with basic concepts and patterns of Blazor, please review the fundamentals before you continue: Introduction to ASP.NET Core Blazor

This tutorial describes how to integrate the JavaScript Dashboard control into a Blazor application.

View Example

Prerequisites

Create a Blazor Application

This solution uses the ASP.NET Core backend (server-side Blazor) to process requests from the JavaScript Dashboard. The client side defines the UI for this component and the logic needed to respond to UI updates.

  1. Create a new Blazor app named BlazorDashboardApp. Select the Blazor WebAssembly App template and enable the ASP.NET Core hosted check box. If this template was not installed, review the following topic: Blazor Tutorial - Build your first Blazor app.

    Alternative. Run dotnet new blazorwasm -n BlazorDashboardApp --hosted command.

Configure the Server Part

  1. Install the following NuGet packages:

    • DevExpress.AspNetCore.Dashboard
    • Microsoft.AspNetCore.Mvc.NewtonsoftJson
  2. Create the App_Data/Dashboards folder to store dashboards.

  3. Open the Startup.cs file and update the ConfigureServices method as follows:

    using DevExpress.AspNetCore;
    using DevExpress.DashboardAspNetCore;
    using DevExpress.DashboardCommon;
    using DevExpress.DashboardWeb;
    using DevExpress.DataAccess.Json;
    using Microsoft.Extensions.FileProviders;
    using System;
    // ...
    public Startup(IConfiguration configuration, IWebHostEnvironment hostingEnvironment) {
        Configuration = configuration;
        FileProvider = hostingEnvironment.ContentRootFileProvider;
    }
    
    public IConfiguration Configuration { get; }
    public IFileProvider FileProvider { get; }
    
    public void ConfigureServices(IServiceCollection services) {
        services.AddResponseCompression(opts => {
            opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "application/octet-stream" });
        });
        services.AddDevExpressControls();
        services.AddMvc()
                .AddDefaultDashboardController(configurator => {
                    // Register Dashboard Storage
                    configurator.SetDashboardStorage(new DashboardFileStorage(FileProvider.GetFileInfo("App_Data/Dashboards").PhysicalPath));
                    // Create a sample JSON data source
                    DataSourceInMemoryStorage dataSourceStorage = new DataSourceInMemoryStorage();
                    DashboardJsonDataSource jsonDataSourceUrl = new DashboardJsonDataSource("JSON Data Source (URL)");
                    jsonDataSourceUrl.JsonSource = new UriJsonSource(
                            new Uri("https://raw.githubusercontent.com/DevExpress-Examples/DataSources/master/JSON/customers.json"));
                    jsonDataSourceUrl.RootElement = "Customers";
                    jsonDataSourceUrl.Fill();
                    dataSourceStorage.RegisterDataSource("jsonDataSourceUrl", jsonDataSourceUrl.SaveToXml());
                    configurator.SetDataSourceStorage(dataSourceStorage);
                });
        services.AddControllersWithViews();
        services.AddRazorPages();
    }
    
  4. In the same file, add the app.UseDevExpressControls() and EndpointRouteBuilderExtension.MapDashboardRoute() method calls to the Configure method in the following order:

    // ...
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
        // ...        
        app.UseStaticFiles();
        app.UseDevExpressControls();
        app.UseRouting();
    
        app.UseEndpoints(endpoints => {
            EndpointRouteBuilderExtension.MapDashboardRoute(endpoints, "api/dashboard");
            // ...
        });
    }
    

Configure the Client Part

  1. Add the npm configuration file (package.json) and list the following npm packages required by the Dashboard component:

    {
        "dependencies": {
            // ...
            "devexpress-dashboard": "~20.2.13"
            "@devexpress/analytics-core": "~20.2.13",
            "devextreme": "~20.2.13",
            "jquery-ui-dist": "1.12.1"
        },
        // ...
    }
    
  2. Right-click the created package.json file and select Restore Packages.

    Alternative. Run npm install to install these packages.

  3. In the Pages folder, create the Dashboard Razor component (Dashboard.razor) and add the code below to render the Web Dashboard:

    @page "/dashboard"
    @inject IJSRuntime JSRuntime
    @implements IDisposable
    
    
    <div id="web-dashboard" style="width: 100%; height: 600px; border: 1px solid rgb(221, 221, 221);">
    </div>
    
    @code {
        protected override void OnAfterRender(bool firstRender) {
            JSRuntime.InvokeAsync<object>("JsFunctions.InitWebDashboard");
        }
    
        public void Dispose() {
            JSRuntime.InvokeAsync<string>("JsFunctions.DisposeWebDashboard");
        }
    }
    

    Note

    You should call the OnAfterRender method for the dashboard component for initialization and the Dispose method to release unused memory.

  4. In the wwwroot folder, create the index.js file and implement the logic to initialize and dispose the components:

    window.JsFunctions = {
        InitWebDashboard: function () {
            this.dashboardControl = new DevExpress.Dashboard.DashboardControl(document.getElementById("web-dashboard"), {
                endpoint: "/api/dashboard"
            });
            this.dashboardControl.render();
        },
        DisposeWebDashboard: function () {
            this.dashboardControl.dispose();
        }
    };
    
  5. Install the BuildBundlerMinifier NuGet package. Create a bundleconfig.json file to bundle scripts and styles required for the Web Dashboard:

    [
        {
            "outputFileName": "wwwroot/site/styles.css",
            "inputFiles": [
                "node_modules/devextreme/dist/css/dx.light.css",
                "node_modules/@devexpress/analytics-core/dist/css/dx-analytics.common.css",
                "node_modules/@devexpress/analytics-core/dist/css/dx-analytics.light.css",
                "node_modules/@devexpress/analytics-core/dist/css/dx-querybuilder.css",
                "node_modules/devexpress-dashboard/dist/css/dx-dashboard.light.min.css"
            ],
            "minify": {
                "enabled": false,
                "adjustRelativePaths": false
            }
        },
        {
            "outputFileName": "wwwroot/site/bundle.js",
            "inputFiles": [
                "./index.js",
                "node_modules/jquery/dist/jquery.min.js",
                "node_modules/jquery-ui-dist/jquery-ui.min.js",
                "node_modules/knockout/build/output/knockout-latest.js",
                "node_modules/ace-builds/src-min-noconflict/ace.js",
                "node_modules/ace-builds/src-min-noconflict/ext-language_tools.js",
                "node_modules/ace-builds/src-min-noconflict/theme-dreamweaver.js",
                "node_modules/ace-builds/src-min-noconflict/theme-ambiance.js",
                "node_modules/devextreme/dist/js/dx.all.js",
                "node_modules/@devexpress/analytics-core/dist/js/dx-analytics-core.min.js",
                "node_modules/@devexpress/analytics-core/dist/js/dx-querybuilder.min.js",
                "node_modules/devexpress-dashboard/dist/js/dx-dashboard.min.js"
            ],
            "minify": {
                "enabled": false
            },
            "sourceMap": false
        }
    ]
    
  6. In the wwwroot folder, open the index.html file and reference the following scripts and stylesheets:

    • site/styles.css
    • site/bundle.js
    • index.js
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
        <title>BlazorDashboardApp</title>
        <base href="/" />
        <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
        <link href="css/app.css" rel="stylesheet" />
        <link href="BlazorDashboardApp.Client.styles.css" rel="stylesheet" />
        <link href="site/styles.css" rel="stylesheet" />
    </head>
    
    <body>
        <div id="app">Loading...</div>
    
        <div id="blazor-error-ui">
            An unhandled error has occurred.
            <a href="" class="reload">Reload</a>
            <a class="dismiss">🗙</a>
        </div>
        <script src="_framework/blazor.webassembly.js"></script>
        <script src="site/bundle.js"></script>
        <script src="index.js"></script>
    </body>
    
    </html>
    
  7. In the Shared/NavMenu.razor file, add a new NavLink component to the list to display the Web Dashboard item in the navigation menu:

    <div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
        <ul class="nav flex-column">
            <!--...-->
            <li class="nav-item px-3">
                <NavLink class="nav-link" href="dashboard">
                    <span class="oi oi-list-rich" aria-hidden="true"></span> Web Dashboard
                </NavLink>
            </li>
        </ul>
    </div>
    

Run the project to see the result: