Add a Document Viewer and Report Designer (JavaScript-Based) to a Project (Blazor Application Created with a Visual Studio Template)
- 8 minutes to read
Prerequisites
- .NET 8.0 or later SDK.
- Visual Studio 2022 with the ASP.NET and web development workload.
Create a New Project
This section describes how to create a new Blazor project. If you want to add Report Viewer to an existing application, go to Step 2.
Click Create a new project on Visual Studio’s start page, select the Blazor Web App template. Select Server from the Interactive Render Mode drop-down list.
Click Next.
Specify the project name and location, and click Next.
Specify additional options, and click Create.
For more information on available Blazor templates, refer to the following topic: Tooling for ASP.NET Core Blazor.
Obtain Your NuGet Feed Credentials
You need to obtain your personal NuGet feed credentials to access required NuGet packages from your project. You can use the NuGet feed URL or feed authorization key to manage DevExpress packages.
Make sure your DevExpress account has access to Blazor Reporting Controls. This products are included in the Universal, DXperience, ASP.NET, and Reporting subscriptions. Refer to the following page for more information: DevExpress Subscriptions.
Use your DevExpress credentials to log into nuget.devexpress.com.
Obtain your NuGet feed credentials and copy them to the clipboard.
You can find the same URL on the Download Manager page.
Create DevExpress NuGet Source
In Visual Studio, select Tools → NuGet Package Manager → Package Manager Settings.
Navigate to NuGet Package Manager → Package Sources. Click the plus button at the top right corner to add a new NuGet package source. Use the following package settings:
Name:
DevExpress
Source: DevExpress NuGet Gallery (
https://nuget.devexpress.com/api/v3/index.json
) if you use the feed key to authenticate. Otherwise, use the NuGet Feed URL (https://nuget.devexpress.com/{your feed authorization key}/api/v3/index.json
).
Click OK.
Make sure the
nuget.org
package source is also enabled.
If you registered the DevExpress NuGet feed with an authorization key, the login form is displayed when you invoke the NuGet Package Manager window for the first time. Enter your credentials as follows:
- User name:
DevExpress
Password: your authorization key
Install the DevExpress Blazor NuGet Packages
Install NuGet packages for Blazor Reporting:
Select Tools → NuGet Package Manager → Manage NuGet Packages for Solution.
In the invoked dialog, open the Browse tab, and install the following NuGet packages:
DevExpress.Blazor
DevExpress.Blazor.Reporting.JSBasedControls
DevExpress.AspNetCore.Reporting
The DevExpress 24.2 Local package is automatically added as a package source to your NuGet configuration files if you used the DevExpress .NET Product Installer.
Build the project.
Refer to the following topic for more information: Install NuGet Packages in Visual Studio, VS Code, and Rider.
Register DevExpress Resources
Register the services required for Blazor Reporting, and specify endpoint routing. For this, call the following methods in the Program.cs file:
using DevExpress.Blazor.Reporting; using DevExpress.XtraReports.Web.Extensions; // ... builder.Services.AddDevExpressBlazorReporting(); // ... app.UseDevExpressBlazorReporting();
Register the DevExpress.Blazor.Reporting namespace in the _Imports.razor file:
@using DevExpress.Blazor.Reporting
Add the Report Storage
Implement the ReportStorageWebExtension descendant to save and load reports.
The code below is a sample storage that uses the file system to store reports. Add the CustomReportStorageWebExtension.cs class file to your project with following content:
using DevExpress.XtraReports.UI; using System.ServiceModel; public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extensions.ReportStorageWebExtension { readonly string reportDirectory = "Reports"; const string FileExtension = ".repx"; public CustomReportStorageWebExtension() { if (!Directory.Exists(reportDirectory)) { Directory.CreateDirectory(reportDirectory); } } public override bool CanSetData(string url) { // Determines whether a report with the specified URL can be saved. // Add custom logic that returns **false** for reports that should be read-only. // Return **true** if no valdation is required. // This method is called only for valid URLs (if the **IsValidUrl** method returns **true**). return true; } public override bool IsValidUrl(string url) { // Determines whether the URL passed to the current report storage is valid. // Implement your own logic to prohibit URLs that contain spaces or other specific characters. // Return **true** if no validation is required. return Path.GetFileName(url) == url; } public override byte[] GetData(string url) { // Uses a specified URL to return report layout data stored within a report storage medium. // This method is called if the **IsValidUrl** method returns **true**. // You can use the **GetData** method to process report parameters sent from the client // if the parameters are included in the report URL's query string. try { if (Directory.EnumerateFiles(reportDirectory).Select(Path.GetFileNameWithoutExtension).Contains(url)) { return File.ReadAllBytes(Path.Combine(reportDirectory, url + FileExtension)); } } catch (Exception) { throw new FaultException(new FaultReason("Could not get report data."), new FaultCode("Server"), "GetData"); } throw new FaultException(new FaultReason(string.Format("Could not find report '{0}'.", url)), new FaultCode("Server"), "GetData"); } public override Dictionary<string, string> GetUrls() { // Returns a dictionary that contains the report names (URLs) and display names. // The Report Designer uses this method to populate the Open Report and Save Report dialogs. return Directory.GetFiles(reportDirectory, "*" + FileExtension) .ToDictionary(x => Path.GetFileNameWithoutExtension(x)); } public override void SetData(XtraReport report, string url) { // Saves the specified report to the report storage with the specified name // (saves existing reports only). var resolvedUrl = Path.GetFullPath(Path.Combine(reportDirectory, url + FileExtension)); if (!resolvedUrl.StartsWith(reportDirectory + Path.DirectorySeparatorChar)) { throw new FaultException("Invalid report name."); } report.SaveLayoutToXml(resolvedUrl); } public override string SetNewData(XtraReport report, string defaultUrl) { // Allows you to validate and correct the specified name (URL). // This method also allows you to return the resulting name (URL), // and to save your report to a storage. The method is called only for new reports. SetData(report, defaultUrl); return defaultUrl; } }
The
HelloWorld
class instance in theReportFactory.Reports
method is a sample XtraReport class created as described in the next section.In Program.cs, register the
CustomReportStorageWebExtension
:using DevExpress.XtraReports.Web.Extensions; // ... builder.Services.AddDevExpressBlazorReporting(); // ... builder.Services.AddScoped<ReportStorageWebExtension, CustomReportStorageWebExtension>();
Important
Register the
ReportStorageWebExtension
after theAddDevExpressBlazorReporting
method.Add a new Reports folder to a project.
The folder name should be specified in the
ReportStorageWebExtension
implementation.
Create a Sample Report
To perform this step, you should install DevExpress Reporting v24.2 on your machine. Refer to the following topic for more information: Run the Installation Wizard - DevExpress Unified Component Installer.
Select Project -> Add New Item… to invoke the Add New Item dialog. Navigate to the Reporting node and select the DevExpress v.24.2 Report item template.
Name the report TestReport.cs and click Add.
Select Blank in the invoked Report Wizard page and click Finish.
Modify the newly created report in the Visual Studio Report Designer. Add a label and type Hello, World!:
Click the report’s smart tag and select Save…:
In the invoked Save As dialog, specify the Reports project folder, Report XML Files (.repx) file type, and the TestReport.repx file name.
Create Routing to Controller Actions
In the Program.cs file, add the following code to map requests to controller actions:
//... builder.Services.AddMvc(); //... app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAntiforgery(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
Implement Default Controllers
- In Visual Studio, create a new Controllers folder.
Add a new class file (ReportingControllers.cs) with the following content:
using DevExpress.AspNetCore.Reporting.QueryBuilder; using DevExpress.AspNetCore.Reporting.QueryBuilder.Native.Services; using DevExpress.AspNetCore.Reporting.ReportDesigner; using DevExpress.AspNetCore.Reporting.ReportDesigner.Native.Services; using DevExpress.AspNetCore.Reporting.WebDocumentViewer; using DevExpress.AspNetCore.Reporting.WebDocumentViewer.Native.Services; public class CustomWebDocumentViewerController : WebDocumentViewerController { public CustomWebDocumentViewerController(IWebDocumentViewerMvcControllerService controllerService) : base(controllerService) { } } public class CustomReportDesignerController : ReportDesignerController { public CustomReportDesignerController(IReportDesignerMvcControllerService controllerService) : base(controllerService) { } } public class CustomQueryBuilderController : QueryBuilderController { public CustomQueryBuilderController(IQueryBuilderMvcControllerService controllerService) : base(controllerService) { } }
Add a Document Viewer to a Page
Create a new razor file (DocumentViewer.razor) in the Pages folder. Use the code below to generate a page with a Document Viewer component.
Enable interactivity for DevExpress components:
Make sure the required interactive services are registered.
Add an appropriate render mode attribute to a component’s page.
@page "/documentviewer"
@rendermode InteractiveServer
<DxDocumentViewer ReportName="TestReport" Height="1000px" Width="100%">
<DxDocumentViewerTabPanelSettings Width="340" />
</DxDocumentViewer>
The DxDocumentViewer component invokes the default WebDocumentViewerController that processes requests from the Document Viewer and loads the TestReport report to create a document.
Add a Report Designer to a Page
Create a new razor file (ReportDesigner.razor) in the Pages folder. Use the code below to generate a page with a Report Designer component.
Enable interactivity for DevExpress components:
Make sure the required interactive services are registered.
Add an appropriate render mode attribute to a component’s page.
@page "/reportdesigner"
@rendermode InteractiveServer
<DxReportDesigner ReportName="TestReport" Height="1000px" Width="100%" AllowMDI="true">
<DxReportDesignerWizardSettings UseFullscreenWizard="true" />
</DxReportDesigner>
The DxReportDesigner loads the TestReport report.
Note
If you implement a custom report that inherits from XtraReport and want to open it in the End-User Report Designer, add a constructor without parameters to this report.
Add Navigation Links
Add navigation links to the NavMenu.razor page:
Run the Project
Run the project. The Document Viewer and Report Designer components load the TestReport.repx report:
Next Steps
- Troubleshooting
- Topic lists common issues that can occur in a Web Reporting application and describes solutions. For information on how to identify the cause of an issue, refer to the following topic: Reporting Application Diagnostics.
- Specify Report Parameters
- Topic describes how to specify report parameters using the built-in Parameters Panel or create custom UI elements and use them to submit parameter values to the report.
- Document Viewer Customization
- Topic describes how to specify the Viewer’s properties and handle events to adjust the Document Viewer appearance and behavior.
- Report Designer Customization
- Topic describes how handle events to adjust the Report Designer appearance and behavior.