Search code examples
c#rdlcreportviewern-tier-architecture

How can we get around a ReportViewer's inability to use reports from another project?


I am currently working on a college C# project where I am required to apply N-Tier Architecture with 5 Layers:

  • Data Access
  • SQL Layer
  • Business Layer
  • Desktop Front End
  • Web Front End

One of the requirements of the project is to display reports.

I chose to use ReportViewer and RDLC reports to accomplish this. My choice has been working fine until I reached the final iteration of the project.

Before this iteration, I only had to generate reports from the Desktop application and the RDLC report was inside my Desktop application project. Now I need to generate the report on a ASP.Net WebForm.

Since the report needs to be accessed by 2 different projects, I thought all I had to do was move the RDLC report up a layer, to my Business Layer (probably should have been there anyways, oops). Of course, I ran into problems. It's never that easy, is it?

After some searching I found 2 particular useful posts:

  1. Reportviewer and report are in different projects in the same solution. How do I attach the report to the viewer
  2. https://forum.inductiveautomation.com/t/displaying-a-report-over-multiple-projects/12825

The first post told me all that I would need to do is set the Copy to Output Directory of my RDLC file to Copy always and then set the ReportViewer.LocalReport.ReportPath to the rdlc's file name with the extension ("example.rdlc").

Unfortunately, this answer never worked for both me and the OP. Why it didn't work was explained in the second post:

A report viewer cannot view a report from another project, although this may make a good feature request. - adam.morales

I then tried something a little different. Instead of accessing the report with ReportPath from a different project, why don't I create a property in my business layer that will return a LocalReport that already has the report definition? Unfortunately, ReportViewer.LocalReport is read only. Even if it was writable, I would not be surprised if it didn't solve the issue; because, ReportPath is a string and the issue probably occurs when the LocalReport attempts to render.

This poses a very big problem for me. There is not enough time to completely redo the Reports and I don't want to have to resort to have 2 different RDLC files, 1 for each front end project; because, that's bad design.

To be completely clear on my needs:

  • I need to be able to access a RDLC report from 2 different projects
  • I must follow N-Tier Architecture and keep code reusable

So, that's why I ask, what kind of work-around could I possibly try to remedy this problem?


Solution

  • Well, the best I could find is embedding a PDF into the WinForms. This seems to require third-party DLLs, something I've been trying to avoid; because, it's a college project.

    While this is not tested yet... The LocalReport.Render method can generate a PDF (among a variety of things) as an Byte[]. If I use the Render method inside my Business Layer; then, I would expect it work since LocalReport would do its own thing while in the same project as the RDLC file and therefor work.

    After that I should be able to simply return the generated report and use it where ever I want.

    Unfortunately, I don't want to go through the complexity of adding third-party dlls to the college project so I'm going to simply duplicate the RDLC files... Hate the solution; but, it is what it is.