How to Load Resources in Page/RDL Reports When Previewing in the JSViewer
When it comes to designing Page/RDL reports, it is common to store the report and its resources like images, styles, master reports, etc., at a shared location like in a database or on the cloud so that everyone across the team can use them. This action also keeps the backup safe. However, when a report is rendered in the viewer, the viewer cannot access its resources while looking at the physical location.
Getting Started: WinForms/WPF Viewer vs. JavaScript Viewer
To resolve this problem, ActiveReports provides an abstract class, ResourceLocator, which helps to load the resources at the time of rendering when the viewer cannot find them at the physical location. The documentation provides a detailed implementation if the report is to be rendered in the WinForms/WPF Viewer.
However, the same approach does not work while previewing the report in the JSViewer because viewers differ in terms of rendering methods.
For the JSViewer, you need to use the PersistenceFilter class from the GrapeCity.ActiveReports.Rdl.Persistence namespace to dynamically load the resources in the report. This class is used to perform custom actions on the report object and is used with ResourceLocator to fulfill the purpose. How? Let us demonstrate how by dynamically loading the master report as a resource while previewing the RDL report in the JS viewer.
What is a Master Report
Master Reports are like dynamic templates designed for use with content reports. They help create reports that share common elements such as a logo in the page header or a web site link in the page footer section. Master Reports are designed with controls, code, data sources, and layout properties that cannot be modified from content reports. They are generally placed at a shared location like in a database to be used across the team. However, the JSViewer does not load the master report while previewing the content reports directly. It is important to follow the steps below to achieve the same result.
Loading Master Reports Dynamically in the JavaScript Viewer
To get started, grab the MasterReport from the database using the ResourceLocator:
public class MasterReportResourceLocator : ResourceLocator
{
public override Resource GetResource(ResourceInfo resourceInfo)
{
Resource _resource;
if (resourceInfo.Name.Equals("Master.rdlx-master"))
{
//Getting the Master Report from the DB
var stream = new MemoryStream(GetMasterReport());
if (stream != null)
{
//Assigning the master report to the resource object
_resource = new Resource(stream, null);
}
}
return _resource;
}
}
Now, customize the JSViewer's reporting service to load the MasterReport from the ResourceLocator with help from the PersistenceFilter class.
Building the JavaScript Viewer's Reporting Service
Create the JSViewer reporting service in the "Startup.cs" class:
app.UseReporting(settings =>
{
//Customizing the report service. It will call the GetReport method to get the report content
settings.UseCustomStore(GetReport);
settings.UseCompression = true;
});
Create the GetReport method to load the report Ccntent.
private object GetReport(string arg)
{
baseDirectory = AppDomain.CurrentDomain.BaseDirectory + "\\Reports\\";
string reportPath = baseDirectory + arg;
//Load Content Report from the database
var stream = new MemoryStream(GetContentReport());
// Create the object of the ResourceLocator
var resourceLocator = new MasterReportResourceLocator();
if (stream == null)
throw new ReportNotFoundException();
using (var reader = new StreamReader(stream))
{
//It allows to create the instance of ReportDefinition and bind it with the ResourceLocator
var report = GrapeCity.ActiveReports.Rdl.Persistence.PersistenceFilter.Load(reader, resourceLocator);
report.Site = new ReportSite(resourceLocator);
if (string.IsNullOrEmpty(report.Name))
report.Name = arg;
report.DataSources[0].ConnectionProperties.ConnectString = String.Format("provider=Microsoft.Jet.OLEDB.4.0;data source={0}MasterData.mdb;", baseDirectory);
return report;
}
Use the ISite to bind the ResourceLocator with the report.
public class ReportSite : ISite
{
private readonly ResourceLocator _resourceLocator;
public ReportSite(ResourceLocator resourceLocator)
{
_resourceLocator = resourceLocator;
}
public object GetService(Type serviceType) =>
serviceType == typeof(ResourceLocator) ? _resourceLocator : null;
public IComponent Component => null;
public IContainer Container => null;
public bool DesignMode => false;
public string Name { get; set; }
}
Download the sample here.
Moving Forward with Other Resources in the JSViewer
And this is done. Follow the same approach to load any other type of resource in your Page/RDL reports. If you are trying to load any other resource type in your reports and need help previewing in the JSViewer, please add a comment in the section below.
Try ActiveReportsJS free for 30 days
Deliver customized, professional reports in less time
Download Now!