Add Web Report Designer in Blazor application
This section explains the steps required to add web Report Designer version higher than v8.1.xx to a Blazor application.
To get started quickly with Report Designer, you can check out this video:
Prerequisites
Before getting started with bold web report designer, make sure your development environment includes the following requirements.
- Visual Studio 2022 with ASP.NET and Web Development workloads.
- .NET Core 8.0 / 9.0 Framework.
Create a Blazor application
- Start Visual Studio 2022 and click Create new project.
- Choose Blazor Web App, then click Next.

- Modify the project name to
BlazorReportingTools, then click Next. - From the dropdown menu for Framework, choose .NET 8.0 or .NET 9.0, and then click Create.

The source code for this Blazor reporting components app is available on GitHub.
List of dependency libraries
- In the Solution Explorer tab, right-click the project or solution, and choose Manage NuGet Packages. Alternatively, select the Tools > NuGet Package Manager > Manage NuGet Packages for Solution menu command.
- Search for the
BoldReports.Net.Corepackage, and install them in your Blazor application. The following table provides details about the packages and their usage.
| Package | Purpose |
|---|---|
BoldReports.Net.Core |
Creates a Web API service used to process the reports. |
Microsoft.AspNetCore.Mvc.NewtonsoftJson |
ASP.NET Core MVC features that use Newtonsoft.Json. Includes input and output formatters for JSON and JSON Patch. The package version should be 8.0.0 or higher. |
Microsoft.Data.SqlClient |
This is an optional package for the report viewer and designer. It should be referred in project when process the RDL report and which contains the SQL Server and SQL Azure data source. Also, the package version should be 5.1.0 or higher. |
Refer to the NuGet Packages section to learn more details about installing and configuring Report Designer NuGet packages.
Add Web API Controller
-
Right-click the project and select Add > New Item from the context menu.
-
In the Add New Item dialog, select API Controller Empty class and name it as
BoldReportsAPIController.cs.
-
Click Add.
While adding the API Controller class, it is mandatory to name it with the suffix
Controller.
Configure Web API
The IReportDesignerController interface contains the required actions and helper methods declaration to process the designer file and data actions. The ReportDesignerHelper and ReportHelper class contains methods that help to process Post or Get request from the control and return the response.
| Methods | Description |
|---|---|
| PostDesignerAction | Action (HttpPost) method for posting the request for designer actions. |
| UploadReportAction | Action (HttpPost) method for posted file actions. |
| SetData | Writes the resource into storage location. |
| GetData | Reads the resource from storage location. |
| GetImage | Action (HttpGet) method for getting resource of images in the report. |
| PostReportAction | Action (HttpPost) method for posting the request for report process. |
| GetResource | Action (HttpGet) method for getting resource for report. |
| OnInitReportOptions | Report initialization method that occurs when the report is about to be processed. |
| OnReportLoaded | Report loaded method that occurs when the report and sub report start loading. |
ReportDesignerHelper
The class ReportDesignerHelper contains helper methods that help to process Post or Get request from the Report Designer control and returns the response to the Report Designer control. It has the following methods.
| Methods | Description |
|---|---|
| GetResource | Returns the report resource for the requested key. |
| ProcessReport | Processes the report request and returns the result. |
ReportHelper
The class ReportHelper contains helper methods that help process Post or Get request for report preview action and returns the response to the Report Designer. It has the following methods.
| Methods | Description |
|---|---|
| GetResource | Returns the report resource for the requested key. |
| ProcessReport | Processes the report request and returns the result. |
-
Open the
BoldReportsAPIControllerand add the following codes.using BoldReports.Web.ReportViewer; using Microsoft.AspNetCore.Hosting; using BoldReports.Web.ReportDesigner; using Microsoft.Extensions.Caching.Memory; using Microsoft.AspNetCore.Mvc; namespace BlazorReportingTools { [Route("api/{controller}/{action}/{id?}")] public class BoldReportsAPIController : ControllerBase, IReportDesignerController { private Microsoft.Extensions.Caching.Memory.IMemoryCache _cache; private IWebHostEnvironment _hostingEnvironment; public BoldReportsAPIController(Microsoft.Extensions.Caching.Memory.IMemoryCache memoryCache, IWebHostEnvironment hostingEnvironment) { _cache = memoryCache; _hostingEnvironment = hostingEnvironment; } /// <summary> /// Get the path of specific file /// </summary> /// <param name="itemName">Name of the file to get the full path</param> /// <param name="key">The unique key for report designer</param> /// <returns>Returns the full path of file</returns> [NonAction] private string GetFilePath(string itemName, string key) { string rootPath = this._hostingEnvironment.WebRootPath ? this._hostingEnvironment.WebRootPath : this._hostingEnvironment.ContentRootPath; string dirPath = Path.Combine(rootPath, "Cache", key); if (!System.IO.Directory.Exists(dirPath)) { System.IO.Directory.CreateDirectory(dirPath); } return Path.Combine(dirPath, itemName); } /// <summary> /// Action (HttpGet) method for getting resource of images in the report. /// </summary> /// <param name="key">The unique key for request identification.</param> /// <param name="image">The name of requested image.</param> /// <returns>Returns the image as HttpResponseMessage content.</returns> public object GetImage(string key, string image) { return ReportDesignerHelper.GetImage(key, image, this); } /// <summary> /// Send a GET request and returns the requested resource for a report. /// </summary> /// <param name="resource">Contains report resource information.</param> /// <returns> Resource object for the given key</returns> public object GetResource(ReportResource resource) { return ReportHelper.GetResource(resource, this, _cache); } /// <summary> /// Report Initialization method that is triggered when report begin processed. /// </summary> /// <param name="reportOptions">The ReportViewer options.</param> [NonAction] public void OnInitReportOptions(ReportViewerOptions reportOption) { //You can update report options here } /// <summary> /// Report loaded method that is triggered when report and sub report begins to be loaded. /// </summary> /// <param name="reportOptions">The ReportViewer options.</param> [NonAction] public void OnReportLoaded(ReportViewerOptions reportOption) { //You can update report options here } /// <summary> /// Action (HttpPost) method for posting the request for designer actions. /// </summary> /// <param name="jsonData">A collection of keys and values to process the designer request.</param> /// <returns>Json result for the current request.</returns> [HttpPost] public object PostDesignerAction([FromBody] Dictionary<string, object> jsonResult) { return ReportDesignerHelper.ProcessDesigner(jsonResult, this, null, this._cache); } /// <summary>Action (HttpPost) method for posting the request for designer actions.</summary> /// <returns>Json result for the current request.</returns> public object PostFormDesignerAction() { return ReportDesignerHelper.ProcessDesigner(null, this, null, this._cache); } public object PostFormReportAction() { return ReportHelper.ProcessReport(null, this, this._cache); } /// <summary> /// Action (HttpPost) method for posting the request for report process. /// </summary> /// <param name="jsonResult">The JSON data posted for processing report.</param> /// <returns>The object data.</returns> [HttpPost] public object PostReportAction([FromBody] Dictionary<string, object> jsonResult) { return ReportHelper.ProcessReport(jsonResult, this, this._cache); } /// <summary> /// Sets the resource into storage location. /// </summary> /// <param name="key">The unique key for request identification.</param> /// <param name="itemId">The unique key to get the required resource.</param> /// <param name="itemData">Contains the resource data.</param> /// <param name="errorMessage">Returns the error message, if the write action is failed.</param> /// <returns>Returns true, if resource is successfully written into storage location.</returns> [NonAction] bool IReportDesignerController.SetData(string key, string itemId, ItemInfo itemData, out string errorMessage) { errorMessage = string.Empty; if (itemData.Data != null) { System.IO.File.WriteAllBytes(this.GetFilePath(itemId, key), itemData.Data); } else if (itemData.PostedFile != null) { var fileName = itemId; if (string.IsNullOrEmpty(itemId)) { fileName = System.IO.Path.GetFileName(itemData.PostedFile.FileName); } using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) { itemData.PostedFile.OpenReadStream().CopyTo(stream); byte[] bytes = stream.ToArray(); var writePath = this.GetFilePath(fileName, key); System.IO.File.WriteAllBytes(writePath, bytes); stream.Close(); stream.Dispose(); } } return true; } /// <summary> /// Gets the resource from storage location. /// </summary> /// <param name="key">The unique key for request identification.</param> /// <param name="itemId">The unique key to get the required resource.</param> /// <returns>Returns the resource data and error message.</returns> [NonAction] public ResourceInfo GetData(string key, string itemId) { var resource = new ResourceInfo(); try { var filePath = this.GetFilePath(itemId, key); if (itemId.Equals(Path.GetFileName(filePath), StringComparison.InvariantCultureIgnoreCase) && System.IO.File.Exists(filePath)) { resource.Data = System.IO.File.ReadAllBytes(filePath); } else { resource.ErrorMessage = "File not found from the specified path"; } } catch (Exception ex) { resource.ErrorMessage = ex.Message; } return resource; } /// <summary> /// Action (HttpPost) method for posted or uploaded file actions. /// </summary> [HttpPost] public void UploadReportAction() { ReportDesignerHelper.ProcessDesigner(null, this, this.Request.Form.Files[0], this._cache); } } }- To request the report processing unit properly, we changed the router API attribute to include the controller and action names using
[Route("api/{controller}/{action}/{id?}")].
- To request the report processing unit properly, we changed the router API attribute to include the controller and action names using
-
To invoke this Web API with the controller and action, we have to include
AddControllers()andAddMemoryCache()builder services andMapControllers()in theProgram.csfile.builder.Services.AddControllers(); builder.Services.AddMemoryCache(); ... ... ... app.MapControllers(); -
You can replace the below template code in the
Program.csfile.using BlazorReportingTools.Components; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddMemoryCache(); builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error", createScopeForErrors: true); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAntiforgery(); app.MapControllers(); app.MapRazorComponents<App>() .AddInteractiveServerRenderMode(); app.Run();
Initialize the Report Designer
In this section, we are going to integrate Bold Reports® JavaScript controls by creating an interop file to initialize the report designer with basic parameters.
-
Right-click the project and select Add > Class from the context menu.
-
In the Add New Item dialog, select class and name it as
BoldReportDesignerOptions.cs.
-
Click Add.
-
Add the following code to the
BoldReportDesignerOptions.csfile to hold the RDL report rendering properties.namespace BlazorReportingTools { public class BoldReportDesignerOptions { public string ServiceURL { get; set; } } } -
Create a
boldreports-interop.jsfile inside thewwwroot/scriptsfolder and use the following code snippet to invoke the Bold Report Designer JavaScript control.// Interop file to render the Bold Report Designer component with properties. window.BoldReports = { RenderDesigner: function (elementID, reportDesignerOptions) { $("#" + elementID).boldReportDesigner({ serviceUrl: reportDesignerOptions.serviceURL }); } } -
Reference the following online CDN links along with the
boldreports-interop.jsinterop file in the head section of theComponents/Layout/MainLayout.razorfile to use our JavaScript reporting controls in the Blazor application.<!-- Report Designer component styles --> <link href="https://cdn.boldreports.com/13.1.26/content/v2.0/tailwind-light/bold.report-designer.min.css" rel="stylesheet" /> <link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/codemirror.min.css" rel="stylesheet" /> <link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/hint/show-hint.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/codemirror.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/hint/show-hint.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/hint/sql-hint.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/sql/sql.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/vb/vb.min.js" type="text/javascript"></script> <!-- Report Designer component dependent scripts --> <script src="https://cdn.boldreports.com/13.1.26/scripts/v2.0/common/bold.reports.common.min.js"></script> <script src="https://cdn.boldreports.com/13.1.26/scripts/v2.0/common/bold.reports.widgets.min.js"></script> <!-- Report Viewer and Designer component scripts --> <script src="https://cdn.boldreports.com/13.1.26/scripts/v2.0/bold.report-viewer.min.js"></script> <script src="https://cdn.boldreports.com/13.1.26/scripts/v2.0/bold.report-designer.min.js"></script> <!-- Blazor interop file --> <script src="scripts/boldreports-interop.js"></script> -
Inject IJSRuntime and add InteractiveServer rendermode and invoke this JavaScript interop and the created
BoldReportsAPIURL in theComponents/Pages/Home.razorfile to visualize the report designer.@page "/" @rendermode InteractiveServer @using Microsoft.JSInterop @using Microsoft.AspNetCore.Components @inject IJSRuntime JSRuntime @using BlazorReportingTools; <div id="designer" style="width: 100%;height: 950px"></div> @code { // ReportDesigner options BoldReportDesignerOptions designerOptions = new BoldReportDesignerOptions(); // Used to render the Bold Report Designer component in Blazor page. public async void RenderReportDesigner() { designerOptions.ServiceURL = "https://demos.boldreports.com/services/api/ReportingAPI"; await JSRuntime.InvokeVoidAsync("BoldReports.RenderDesigner", "designer", designerOptions); } // Initial rendering of Bold Report Designer protected override void OnAfterRender(bool firstRender) { RenderReportDesigner(); } }
Here we created and used BoldReportDesignerOptions to pass the parameters for report designer. In the future, if we need any additional parameters, we can just include them in the BoldReportDesignerOptions.cs file.
Run the Application
Click Run or F5 button to launch the application.

Note: You can refer to our feature tour page for the Blazor Report Designer to see its innovative features. Additionally, you can view our Blazor Report Designer examples which demonstrate the rendering of SSRS RDLC and RDL reports.