Telerik blogs

It’s easy to switch between Telerik Reporting REST Service and Report Server. Here’s briefly how to do that and pros and cons of each method.

What I am achieving with this post is to show how easy it is to swap between the two methods of rendering reports—with Telerik Report Server (TRS) and with Telerik Reporting REST. I will also show the pros and cons of each method and how to run both solutions alongside each other with a switch to swap between the two. This article is not really intended as a comprehensive how-to article—however, you are welcome to quiz me on how I achieved the more technical aspects of the switching.

One thing to note: It takes a bit of setting up. You need already to have an ASP.NET Core site. This is used to “call” both the TRS and REST Reporting instances via the HTML5 Telerik Report viewer.

Initial Setup

For the initial setup to switch between TRS and REST Reporting, we need to do the following:

TRS: Set up a TRS Instance

Make sure the version matches the version of Telerik Reporting on the ASP.NET Core site.

  1. Either set up a subdomain off your main site or run off localhost on a port. Note: the subdomain version requires a Telerik license, and the localhost does not.
  2. Copy over the website from the installation folder to the physical hosting area.
  3. Modify the connection string area and the TRS instance should start to work.

REST Reporting: Create a Telerik REST Reporting Site

  1. This involves creating a Telerik Reporting REST Service project. Note: In my case, I created a .NET Framework version of the Reporting REST service. This is because I already had some User Functions in a .NET Framework Project, and these would not work in a .NET Core environment. Also note: It is possible to call the .NET Framework project from the .NET Core Website and .NET Core Worker (i.e., it is not necessary to have a UI to call the REST project).

    (Alternatively, you can use the project named CSharp.NetFramework.ReportingRestServiceCorsDemo.csproj, which is distributed with product installation, as a template. This may speed things up if you are not familiar with CORS configuration. Note: This can be used via the initial Visual Studio Project dialog.)

    It is necessary to decorate the Controller class with the following—otherwise, there shall be a CORS error.

[EnableCors(origins: "https://staging.buku.uk"
    , headers: "*", methods: "*")
        ]
            public class ReportsController : ReportsControllerBase
            
            
  1. Also, it is necessary to place some reports into a directory called Reports off the root of the project. You can separate the reports using sub-directories.

  2. I use a custom report resolver to “magically” fix up the connection string, and parameters that are supplied by the calling function. In most cases, this is a Telerik HTML5 Report Viewer. However, background tasks can be run from the always-on Worker process.

    Note: The Booking.Data.NET.Classes.Configuration._sBookingConnectionString property resolves to a connectionstring based on the _nServerInstance variable. i.e. Dev, Staging or Live.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using Telerik.Reporting;
using Telerik.Reporting.Services;
using Booking.Library.NET.Classes;

namespace Booking.Reporting.NET.REST.Classes
{
  public class CustomReportSourceResolver : IReportSourceResolver
  {
    public string ReportsPath { get; set; }

    public CustomReportSourceResolver(string reportsPath)
    {
      this.ReportsPath = reportsPath;
    }

    public ReportSource Resolve(string reportId, OperationOrigin operationOrigin, IDictionary<string, object> currentParameterValues)
    {
      try
      {
        string reportPath = Path.Combine(this.ReportsPath, reportId);
        var reportPackager = new ReportPackager();
        Report report = null;
        using (var sourceStream = System.IO.File.OpenRead(reportPath))
        {
          report = (Report)reportPackager.UnpackageDocument(sourceStream);
        }
        if (currentParameterValues.Any(CPV => CPV.Key == "nServerInstance"))
        {
          var lnServerInstance = currentParameterValues.Where(CPV => CPV.Key == "nServerInstance").FirstOrDefault().Value;
          Booking.Data.NET.Classes.Configuration._nServerInstance = (int)(long)lnServerInstance;
        }
        ReportConnectionStringManager loReportConnectionStringManager = new ReportConnectionStringManager(Booking.Data.NET.Classes.Configuration._sBookingConnectionString);
        ReportSource loReportSource = loReportConnectionStringManager.UpdateReportSource(new InstanceReportSource() { ReportDocument = report });
        foreach (var parameter in currentParameterValues)
        {
          loReportSource.Parameters.Add(parameter.Key, parameter.Value);
        }
        return loReportSource;
      }
      catch (System.Exception loException)
      {
        Logger.LogException(loException);
      }
      return null;
    }
  }
}

Pros and Cons

The pros and cons of selecting one or the other mainly have to do with cost. While TRS is worth every penny, some customers have budgetary constraints which could preclude a sale under certain conditions. The Buku Platform is designed to run on client infrastructure where the client would like this to happen (i.e., their own servers and network, also the product, can run completely on a Windows laptop). So, if every time we found a customer wanting to run the software they also had to purchase TRS, their costs go up significantly.

The REST Solution can render reports the same as the TRS solution and the only cost to the client is hard disk space and computer power. (Underneath the TRS is an implementation of REST Service, which makes such switching scenarios effortless.) Note, there is to be a cloud version also where customers can sign up to use the product, and the data is in the secure cloud.

The TRS solution has some added advantages in the ability to run reports from within the server itself, although we are not using this feature fully in the Buku Platform. Customers see the Buku Platform reporting engine only. Currently, we only offer report design as a consultancy extra. We are planning a Reporting module which would allow custom reports to be designed by the user according to preprogrammed data sources.

So the way the HTML5 Report Viewer is configured is one of the design considerations that makes switching back and forth between TRS and REST possible.

The following is the top part of the report viewer. Several points to note:

  1. TRS has a guest mode that does not require login credentials, as you can see from the lines below the URL.
  2. REST has no authentication method—however, leaving the credential lines where they are is ignored.
  3. The TRS Data Sources are controlled by a TRS data connector, effectively a connection string. There are also some Object Data Sources for some of the smaller reports.
  4. The REST program always uses an _nServerInstance arrangement for determining the connectionstring depending on whether Dev, Staging or Live.
  5. The different types of reports have different types and numbers of parameters; however, some reports use the same parameters and types of parameters. These can be grouped together using the same block for more than one report.
$(document).ready(function () {
  $("#rvMain").telerik_ReportViewer({
    reportServer: {
      url: "@this.Model._sReportingUrl",
      username: null,
      password: null
    },
    reportSource: {
      report: '@this.Model._sReport',
      parameters: {
        @switch ((Booking.Library.Classes.Enums.Reports)this.Model._nReport)
        {
          case Booking.Library.Classes.Enums.Reports.AdHocSLInvoice1:
          case Booking.Library.Classes.Enums.Reports.AdHocSLInvoice2:
          case Booking.Library.Classes.Enums.Reports.AdHocSLCreditNote1:
          case Booking.Library.Classes.Enums.Reports.AdHocSLCreditNote2:
          case Booking.Library.Classes.Enums.Reports.AdHocPLInvoice1:
          case Booking.Library.Classes.Enums.Reports.AdHocPLInvoice2:
          case Booking.Library.Classes.Enums.Reports.AdHocPLCreditNote1:
          case Booking.Library.Classes.Enums.Reports.AdHocPLCreditNote2:
          case Booking.Library.Classes.Enums.Reports.AdHocPLPayment:
          case Booking.Library.Classes.Enums.Reports.AdHocSLReceipt:
          {
            <text>
              nServerInstance: @Booking.Data.Classes.Configuration._nServerInstance,
              gTransactionId: '@this.Model._gId.ToString()',
              gCompanyId: gCompanyId,
              sCulture: sCompanyCulture
            </text>
          }
            break;
          case Booking.Library.Classes.Enums.Reports.AdHocDisbursementBatch:
          {
            <text>
              nServerInstance: @Booking.Data.Classes.Configuration._nServerInstance,
              gBatchId: '@this.Model._gId.ToString()',
              sCulture: sCompanyCulture
            </text>
          }
            break;
          case Booking.Library.Classes.Enums.Reports.DisbursementBatch:
          {
            <text>
              nServerInstance: @Booking.Data.Classes.Configuration._nServerInstance,
              gCompanyId: gCompanyId,
              dStart: kendo.parseDate('@this.Model._dStart.ToString("dd/MM/yyyy")', "dd/MM/yyyy"),
              dEnd: kendo.parseDate('@this.Model._dEnd.Date.AddDays(1).ToString("dd/MM/yyyy")', "dd/MM/yyyy"),
              bPosted: '@this.Model._bPosted.ToString().ToLower()',
              nReport: @this.Model._nReport,
              bAll: '@this.Model._bAll.ToString().ToLower()' == 'true',
              sCulture: sCompanyCulture
            </text>
          }
            break;
          case Booking.Library.Classes.Enums.Reports.AdHocJournalBatch:

In some ways the REST report has an easier mechanism for keeping the reports up to date. The report on disk is the latest and always gets saved back to the disk. The TRS reports need to be published back to the server.

In order to manage the switching, I use two controls, a switch and a TRS / REST Url field. The switch is simply TRS on or off. The Field containing the Url would have for TRS https://trs.buku.uk and REST https://rs.buku.uk (Reports Staging (RS)).

Switching back to TRS after using REST is a bit of a bind as often the Reports are not up to date on TRS so they need to be pushed over again.


Learn More

For further reading, this blog post covers more about how you can combine and customize Telerik Report Server and Telerik Reporting [SDK]: Telerik Reporting [SDK] & Report Server: The Dynamic Duo of Reporting.

Both reporting products offer a free trial, so you can start experimenting today:

Try Telerik Reporting Try Telerik Report Server

Better yet, both Telerik Reporting and Telerik Report Server are available in the Telerik DevCraft Ultimate Bundle—along with our .NET and JavaScript UI libraries, automated testing, mocking tools and more. Explore this robust free trial today!

Try Telerik DevCraft


About the Author

David Robertson

David Robertson is a software developer/computer scientist, with degrees and many years’ experience working and writing in the field. He also enjoys ethos and philosophical discussions about computing—where he sees it going and the journey so far. He believes in balance within the tech industry and supports it at every juncture, supporting and advocating for good mental health as a way forward for reasonable and reasoned programming.

 

Related Posts

Comments

Comments are disabled in preview mode.