Microsoft has long introduced a framework for creating an interactive web interface with C#, HTML and CSS. It comes in two versions: Server-side (Blazor Server) and Client-side (Blazor WebAssembly). WebAssembly is particular because it is executed right in the user’s browser and accesses the remote server only for the libraries required for code execution.
FastReport .NET already supports Blazor technology as part of the FastReport.Web package (more). However, until now, we have only supported Server-side rendering (Blazor Server). It took us a long time to get FastReport .NET working right in the user’s browser because we needed Skia support for stable work. Starting with version 2023.2, we are pleased to announce Blazor WebAssembly support as part of the FastReport.Blazor.Wasm package. This package is available as part of a FastReport .NET Enterprise subscription and higher (including Ultimate).
Attention! Blazor WebAssembly support is currently in beta. Some reports and functionality may not work. Read the documentation and restrictions carefully before using.
Let’s create a test demo application to see the work of FastReport in WebAssembly.
First, install WebAssembly Build Tools to build your project with WebAssembly. If it is not installed, then run the following commands on the command line, depending on the TargetFramework of your application:
For .NET 6:
dotnet workload install wasm-tools-net6
For .NET 7:
dotnet workload install wasm-tools
Now let’s create a simple Blazor WebAssembly demo project from a template. You can do this using Microsoft Visual Studio 2022 or the dotnet CLI. For simplicity, let’s use the command:
dotnet new blazorwasm -n BlazorWasmDemo
Let’s edit the csproj of our project and add the latest FastReport.Blazor.Wasm package:
<ItemGroup> <PackageReference Include="FastReport.Blazor.Wasm" Version="2023.2.0" /> </ItemGroup>
Now, if you want to prepare your report in the browser (.frx), you must disable Trimming, as it interferes with the report script compilation. You can do this in the following way:
<PropertyGroup> <PublishTrimmed>false</PublishTrimmed> </PropertyGroup>
Now we add the native SkiaSharp libraries as part of our application. Depending on the TargetFramework we need to add:
For .NET 6:
<ItemGroup> <NativeFileReference Include="$(HarfBuzzSharpStaticLibraryPath)\2.0.23\*.a" /> <NativeFileReference Include="$(SkiaSharpStaticLibraryPath)\2.0.23\*.a" /> </ItemGroup>
For .NET 7:
<ItemGroup> <NativeFileReference Include="$(HarfBuzzSharpStaticLibraryPath)\3.1.12\*.a" /> <NativeFileReference Include="$(SkiaSharpStaticLibraryPath)\3.1.12\st\*.a" /> </ItemGroup>
In the _Imports.razor file, similarly to the Blazor Server components, add the necessary namespace to view the FastReport components:
@using FastReport.Web @using FastReport.Web.Blazor.Components
Register FastReport services in our DI container (file Program.cs):
builder.Services.AddScoped(_ => new HttpClient{ BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddFastReport();
Note that for FastReport to work in WebAssembly, you must have a configured HttpClient in a DI container that can access root to load the necessary dlls builds. If you need to override HttpClient for your use, you can just set a separate HttpClient only for FastReport needs:
builder.Services.AddFastReport(options => options.HttpClient = new HttpClient{ BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)});
We have almost completed our long journey of preparing FastReport in WebAssembly, but there are just a few finishing touches. In the standard wwwroot\index.html file, we need to add the loading of js scripts for the proper work of FastReport:
<script src="./_content/FastReport.Web/scripts.js"></script>
FastReport must interact with the user’s fonts since FastReport works with reports and the font is an integral part of any report with text. This is what happens when the report generator runs on Windows or Linux. However, the information about installed fonts on the user’s computer becomes unavailable when FastReport runs in a browser. Thus, our application must register the fonts that we will use in our reports. In our application, we will use a font that we will embed in our library as an embedded resource (EmbeddedResource) in advance. For this, specify in our project (.csproj):
<ItemGroup> <EmbeddedResource Include="Fonts\**"> <Link>Fonts\%(RecursiveDir)%(Filename)%(Extension)</Link> </EmbeddedResource> </ItemGroup>
Let’s put all the fonts we need in the Fonts folder and register them in our Program.cs. Let’s create this method and call it immediately:
static void AddFonts() { var resources = Assembly.GetExecutingAssembly().GetManifestResourceNames(); foreach (var resource in resources) { using var font = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource); FastReport.Utils.Config.PrivateFontCollection.AddFontFromStream(font); } } AddFonts();
That’s quite difficult. Few database connectors can work directly from the user’s browser. Therefore, we leave this to the discretion of our users. For example, you can request data from some third-party resource via HTTP and then register this data in a report before preparing it. In our application, for demonstration, we use the data from the xml file, which we put in wwwroot together with the report.
Attention! Do not use this method for the final project publication because hackers can easily steal your data.
Finally, let’s change the file Index.razor to use our WebReportContainer component. It will require the following code:
@page "/" @using FastReport @using System.Data; @inject HttpClient HttpClient @if (isReady) { <WebReportContainer WebReport="myWebReport" /> } @code{ WebReport myWebReport; private bool isReady = false; protected async override Task OnParametersSetAsync() { // We receive a report var reportBytes = await HttpClient.GetByteArrayAsync("Simple List.frx"); var reportStream = new MemoryStream(reportBytes); var report = Report.FromStream(reportStream); // Get xml database and register it var dataBytes = await HttpClient.GetByteArrayAsync("nwind.xml"); var dataSet = new DataSet(); dataSet.ReadXml(new MemoryStream(dataBytes)); report.RegisterData(dataSet, "NorthWind"); // Create a WebReport and assign a report to it myWebReport = new WebReport() { Report = report, EmbedPictures = true }; isReady = true; } }
Everything went well if we saw our report in the browser:
You have access to the reporting engine, you can build reports and view ready-made. Online designer support will be added in future. For security reasons, database connections are disabled inside reports, you will need to connect data from your application yourself. We are working hard on improving our WebAssembly component. If you have any questions, write to our support at support@fast-report.com.