Create a Blazor Dashboard Application
- 4 minutes to read
This tutorial describes how to integrate the Web Dashboard into a Blazor application.
Note
Note that we do not have a native Dashboard UI component for Blazor. You can only integrate the client HTML JavaScript Dashboard into a Blazor application.
Tip
Example on GitHub: How to use DevExpress HTML JavaScript Dashboard control in Blazor applications
Prerequisites
- Visual Studio 2019 with the ASP.NET and Web Development workload
- .NET Core 3+
- DevExpress Universal Subscription v20.1
Create a Blazor Application
This solution uses the ASP.NET Core backend (server-side Blazor) to process requests from the HTML JS Dashboard. The client side defines the UI for this component and the logic needed to respond to UI updates.
Select the Blazor WebAssembly App template to create a new Blazor application 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 –-hosted
command.
Configure the Server Part
Install the following NuGet packages:
DevExpress.AspNetCore.Dashboard
Microsoft.AspNetCore.Mvc.NewtonsoftJson
Tip
Documentation: Install DevExpress Controls Using NuGet Packages
Create the
App_Data/Dashboards
folder to store dashboards.Open the
Startup.cs
file and update theConfigureServices
method as follows:using DevExpress.AspNetCore; using DevExpress.DashboardAspNetCore; using DevExpress.DashboardCommon; using DevExpress.DashboardWeb; using DevExpress.DataAccess.Json; 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(); }
In the same file, add the
app.UseDevExpressControls()
andEndpointRouteBuilderExtension.MapDashboardRoute()
method calls to theConfigure
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
Add the
package.json
configuration file and list the following npm packages required by our Dashboard component:{ "dependencies": { // ... "devexpress-dashboard": "~20.1.17" "@devexpress/analytics-core": "~20.1.17", "devextreme": "~20.1.17", "jquery-ui-dist": "1.12.1" }, // ... }
Right-click the created
package.json
file and select Restore Packages.Alternative. Run
npm install
to install these packages.Create the
Dashboard.razor
file 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 theDispose
method to release unused memory.In the
wwwroot
folder, create theindex.js
file and implement the logic to initialize and dispose the components:window.JsFunctions = { InitWebDashboard: function () { DevExpress.Dashboard.ResourceManager.embedBundledResources(); this.dashboardControl = new DevExpress.Dashboard.DashboardControl(document.getElementById("web-dashboard"), { endpoint: "/api/dashboard" }); this.dashboardControl.render(); }, DisposeWebDashboard: function () { this.dashboardControl.dispose(); } };
Install the
BuildBundlerMinifier
NuGet package. Create abundleconfig.json
file to bundle scripts and styles required for the Web Dashboard:[ { "outputFileName": "wwwroot/site/styles.css", "inputFiles": [ "node_modules/devextreme/dist/css/dx.common.css", "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.js", "node_modules/jquery-ui-dist/jquery-ui.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 } ]
In the
wwwroot
folder, registerindex.js
and the bundled resources in theindex.html
file: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="site/styles.css" rel="stylesheet" /> </head> <body> <app>Loading...</app> <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>
In the
Shared/NavMenu.razor
file, add a new<li>
element 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: