Hrvoje Batrnek
Hrvoje Batrnek

Reputation: 565

How to render RDLC reports in a desktop application using .NET 5.0?

My application is a desktop WPF/WinForms application with around a hundred reports heavily customized, some even use code in the report itself. I am willing to lose the report viewer but I need a report renderer for PDF, Excel, and Word.

Upvotes: 1

Views: 3156

Answers (2)

Al Banna Techno logy
Al Banna Techno logy

Reputation: 359

I am in the same situation, and I found that the best way to solve this the issue is to isolate the report project into separated service or exe app,

then use Inter-process communication to communicate between your app and the reports system.

The best options I found are

  • MagicOnion

    • because it built on top of gRPC but without the complexity of writing .proto(protocol buffer) contract, and it can directly map the contract data to .Net Types
    • the problem here is the server must be a .Net App, so you should make your main app the server, then make report app/service: the client
  • Pipes, it works very well, but read the documentation carefully to be sure that it is satisfied your needs

  • grpc-dotnet-namedpipes This is maybe better in your case because it is

    • Windows named pipe transport for gRPC in C#/.NET: so high performance
    • Support .NET Framework 4.6+ (Windows): Client and server
    • Support .NET Core 2.1+ (Windows): Client and server
  • For Different Options old/ may legacy Local Machine Interprocess Communication with .NET

Upvotes: 0

Hrvoje Batrnek
Hrvoje Batrnek

Reputation: 565

A desktop app requires Windows (even in .NET 5.0), Windows already have .NET Framework and will support it as long as there are Windows and your desktop app, hence you don't need a service on a server that uses .NET Framework to render your reports. The "simple" solution would be to have a console project that renders reports and uses .NET Framework. All other projects can use .NET standard or .NET 5.0. Console app will of course not have references to your .NET standard or .NET 5.0 projects. I am also having an extra reports project in .NET 5 that will be an implementation for reporting interfaces which I can replace when one day I ditch Framework completely when a full-fledged RDLC renderer appears for new .NET.

.NET 5.0 app will request a report render by calling a console app and getting the rendered report in this way:

.NET 5.0 app:

    var process = new Process();
    var info = new ProcessStartInfo
    {
        FileName = "SyriliumRiF.ReportsGenerator.exe",
        //Arguments = "command line arguments to your executable",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true
    };
    process.StartInfo = info;
    process.Start();

    var base64EncodedData = process.StandardOutput.ReadToEnd();
    var reportBytes = System.Convert.FromBase64String(base64EncodedData);

Console .NET Framework app:

class Program
{
    static void Main(string[] args)
    {
        byte[] reportBytes = RenderReport(args);
        string str = Convert.ToBase64String(reportBytes);
        Console.Write(str);
    }
}

My calls to report viewer in .NET 5 app did not change and I am not generating data sources for the reports in the Framework render app.

Inputs that the render console app receives: report name, report parameters, and files with xml serialized DataTables. In this way, I was able to detach from .NET Framework and have over 100 reports rendering in just a few days of work.

Upvotes: 4

Related Questions