Repository navigation
Migration to 26x
Version naming: what was planned as "version 5" ships as the 26.x.x versions (for example 26.0.x). Older text, issues and NuGet release notes that say "v5" or "5.x" mean the 26.x line.
Migrating from Majorsilence Reporting (My-FyiReporting) version 4 to version 26.x marks a significant shift from legacy .NET Framework dependencies to a modern, cross-platform architecture.
-
Target Framework Upgrade: The most foundational change is the move from .NET Framework (4.x) or early .NET Core to .NET 8.0 and newer.
-
Rendering Engine Options: Version 26.x introduces SkiaSharp as an optional rendering backend alongside the legacy System.Drawing (GDI+) approach. Opting into SkiaSharp enables native, cross-platform rendering on Linux and macOS (recommended for containerized or non‑Windows hosts), while Windows workflows can continue using the default packages.
-
Linux Native Support: Unlike version 4, which often struggled with server-side rendering on non-Windows hosts, version 26.x is fully optimized for containerized environments (like Docker) using SkiaSharp.
-
Package Consolidation: New NuGet packages ending in .SkiaSharp (e.g., Majorsilence.Reporting.RdlEngine.SkiaSharp) replace the older version 4 libraries.
- Linux/macOS (SkiaSharp, optional):
- dotnet add package Majorsilence.Reporting.RdlCreator.SkiaSharp
- dotnet add package Majorsilence.Reporting.RdlEngine.SkiaSharp
- dotnet add package Majorsilence.Reporting.RdlCri.SkiaSharp
- NuGet (Windows / default packages):
- dotnet add package Majorsilence.Reporting.RdlCreator
- dotnet add package Majorsilence.Reporting.RdlEngine
- dotnet add package Majorsilence.Reporting.RdlCri
- Linux/macOS (SkiaSharp, optional):
- Dependency Cleanup: Removed many legacy dependencies that were tied to the older fyiReporting fork.
- Asynchronous Processing: Version 26.x introduces widespread support for async/await patterns in report generation, improving performance in web-based applications.
- Modern Database Providers: Enhanced support for modern versions of PostgreSQL and SQL Server, dropping support for older, EOL database drivers.
- Improved Font Handling: Because SkiaSharp handles fonts differently than GDI+, version 26.x requires explicit font installation (like ttf-mscorefonts-installer) on Linux to maintain visual parity with Windows-generated reports.
| Component | Version 4 | Version 26.x |
|---|---|---|
| Engine | GDI+ / Windows-centric | SkiaSharp / Cross-platform |
| Designer | Windows-only | Windows-only (Requires .NET 8) |
| PDF Export | Built-in | SkiaSharp-based |
| Linux/macOS | Limited/Experimental | Fully Supported (Core Engine) |
- Retarget projects to .NET 8.0 — v4-era .NET Framework/.NET Core targets are no longer supported.
- Package & namespace changes — many packages renamed to *.SkiaSharp or reorganized; update NuGet refs and using/import statements.
- Rendering backend differences — opting into SkiaSharp can change text measurement, layout, DPI and visual output vs GDI+; expect minor layout/spacing differences.
- Font handling and embedding — SkiaSharp requires explicit fonts on Linux/macOS and different embedding behavior; you must install system fonts (e.g., ttf-mscorefonts) and may need to adjust font fallbacks.
- API surface changes — several sync APIs were converted to async; callers may need async/await and signature changes.
- PDF and export behavior — PDF rendering now SkiaSharp-based; output, metrics, and embedded fonts can differ.
- Database drivers/providers updated — older, EOL providers dropped; connection strings or driver packages may need updates.
- Viewer/designer packaging — viewer and designer controls moved to separate packages and some platforms are now experimental; desktop integration code may require changes.
- Native runtime deps — SkiaSharp requires native libs on Linux/macOS (fontconfig, freetype, libpng, etc.); Docker images and hosts must include them.
- Threading/ownership semantics — SkiaSharp resources have stricter disposal and thread-affinity rules; update resource-management and concurrency patterns.
- Deprecated features/extensions — some legacy fyiReporting extensions and configuration keys were removed; verify custom extensions and config files.
- Build/CI changes — update build images/tooling to .NET 8 SDK and ensure native dependencies are installed for cross-platform CI.
- Root namespace changed to Majorsilence.Reporting
This section is meant to provide breaking changes examples
Majorsilence.Reporting change example
// version 4 namespace
fyiReporting.RdlViewer.RdlViewer rdlViewer1;
// version 26.x namespace
Majorsilence.Reporting.RdlViewer.RdlViewer rdlViewer1;API surface changes — several sync APIs were converted to async; callers may need async/await and signature changes.
mainly some methods are now async and some properties have been removed and replaced with an equivalent async method.
version 4
rdlView.Report.DataSets["Data"].SetData(dataTable);version 26.x, async
var rpt = await rdlView.Report();
await rpt.DataSets["Data"].SetData(dataTable);version 4
rdlView.Report.DataSets["Data"].SetSource("SELECT id, name FROM products");version 26.x, async
var rpt = await rdlView.Report();
rpt.DataSets["Data"].SetSource("SELECT id, name FROM products");
await rdlView.Rebuild();- Namespace/type renamed:
- fyiReporting.RdlViewer.RdlViewer -> Majorsilence.Reporting.RdlViewer.RdlViewer
- Update using directives and NuGet/package references.
- Synchronous API removed -> asynchronous API:
- SourceFile (property) -> SetSourceFile(Uri) async method (await required).
- Report (property) -> Report() async method returning Task (await Report()).
- Rebuild() -> async Rebuild() (await required).
- Call-site changes required:
- Make callers async (async methods, async Main, or block with .GetAwaiter().GetResult()).
- Await SetSourceFile, await Report(), then access DataSets and SetData, then await Rebuild().
- Update all call sites, tests, and any code that relied on the old synchronous behavior.
version 4
var dt = new System.Data.DataTable();
var rdlViewer1 = new fyiReporting.RdlViewer.RdlViewer();
string filepath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SampleApp2-TestReport.rdl");
rdlViewer1.SourceFile = new Uri(filepath);
rdlViewer1.Report.DataSets["Data"].SetData(dt);
rdlViewer1.Rebuild();version 26.x, async
var dt = new System.Data.DataTable();
var rdlViewer1 = new Majorsilence.Reporting.RdlViewer.RdlViewer();
string filepath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SampleApp2-TestReport.rdl");
await rdlViewer1.SetSourceFile(new Uri(filepath));
await (await rdlViewer1.Report()).DataSets["Data"].SetData(dt);
await rdlViewer1.Rebuild();- 26.x made Parse(), RunGetData(...) and RunRender(...) asynchronous. You must await them and make the calling method async (propagate Task return or use async Task).
version 4
var reportSource = System.IO.File.ReadAllText(sourcefile.AbsolutePath);
var rdlp = new RDLParser(reportSource);
var rpt = rdlp.Parse();
rpt.RunGetData(null);
var sg = new Majorsilence.Reporting.Rdl.OneFileStreamGen(savePath, true);
rpt.RunRender(sg, OutputPresentationType.PDF);version 26.x, async
var reportSource = await System.IO.File.ReadAllTextAsync(sourcefile.AbsolutePath);
var rdlp = new RDLParser(reportSource);
var rpt = await rdlp.Parse();
await rpt.RunGetData();
var sg = new Majorsilence.Reporting.Rdl.OneFileStreamGen(savePath, true);
await rpt.RunRender(sg, OutputPresentationType.PDF);