How to implement Telerik Reporting in ASP.NET Core 2.1 MVC

Environment

Product Version 13.0.19.116 and above
Product Progress® Telerik® Reporting
Project Type ASP.NET Core
Preferred Language C Sharp

Description

How to implement the Telerik Reporting engine and viewer in ASP.NET Core MVC project?

Solution

There are some specifics related to ASP.NET Core configuration that we will discuss in the beginning. Please note that the configuration is mostly taken from the official documentation: Configuration in ASP.NET Core.

App configuration in ASP.NET Core uses the new SDK-style project and utilizes appsettings.json as a configuration file. To work these settings in your ASP.NET Core application, it is recommended that you only instantiate a ConfigurationService in your application’s Startup class. Then, use the Options pattern to configure individual settings. For example, the ConnectionStrings setting in JSON-based format would look like this:

{
  ...
  "ConnectionStrings": {
      "Telerik.Reporting.Examples.CSharp.Properties.Settings.TelerikConnectionString": "Data Source=.\\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=true"
  }  
}

This type of connection string lacks information about the data provider and will use System.Data.SqlClient as provider invariant name. When it's necessary to specify a different data provider, the following notation is also supported:

{
  ...
  "ConnectionStrings": {
    "Telerik.Reporting.Examples.CSharp.Properties.Settings.TelerikConnectionString": {
      "connectionString": "Data Source=.\\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=true",
      "providerName": "System.Data.SqlClient"
    }
  }
}

The last supported type of ConnectionStrings configuration uses an array to provide information about each connection string:

{
  ...
  "ConnectionStrings": [
    {
      "name": "Telerik.Reporting.Examples.CSharp.Properties.Settings.TelerikConnectionString",
      "connectionString": "Data Source=.\\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=true",
      "providerName": "System.Data.SqlClient"
    }
  ]
}

For more information about Telerik Reporting JSON-based configuration structure, please refer to the Telerik Reporting Configuration Layout help article.

We have to build the configuration in Startup.cs as we implement a sample ConfigurationService class which ensures reading the appsettings.json as config file and used in the ReportsController constructor:

public class ConfigurationService
{
    public IConfiguration Configuration { get; private set; }

    public IHostingEnvironment Environment { get; private set; }
    public ConfigurationService(IHostingEnvironment environment)
    {
        this.Environment = environment;

        var configFileName = System.IO.Path.Combine(environment.ContentRootPath, "appsettings.json");
        var config = new ConfigurationBuilder()
                        .AddJsonFile(configFileName, true)
                        .Build();

        this.Configuration = config;
    }
}

If we want to inject our configuration to our controllers, we'll need to register it with the runtime. We do so via Startup.ConfigureServices:

IServiceCollection services;

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    this.services = services;
    this.services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });
    this.services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    this.services.AddSingleton<ConfigurationService>();
}

In order to have access to WebRootPath in the ReportsController (I assume that the reports will be stored at wwwroot/Reports directory), we need to register it with the runtime. We do so via Startup.Configure:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    this.services.AddTransient(ctx => new ReportsController(new ConfigurationService(env)));
    ....
}

After the initial configuration is done, you can create ReportsController class which will look like:

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using Microsoft.AspNetCore.Mvc;
using Telerik.Reporting.Cache.File;
using Telerik.Reporting.Services;
using Telerik.Reporting.Services.AspNetCore;

namespace AspNetCoreMvcDemo.Controllers
{
    [Route("api/reports")]
    public class ReportsController : ReportsControllerBase
    {
        readonly string reportsPath = string.Empty;

    //We use the *ConfigurationService* as a parameter for the ReportsController constructor to obtain the configuration information and to access the WebRootPath of the application.
        public ReportsController(ConfigurationService configSvc)
        {
            this.reportsPath = Path.Combine(configSvc.Environment.WebRootPath, "Reports");

            this.ReportServiceConfiguration = new ReportServiceConfiguration
            {
                ReportingEngineConfiguration = configSvc.Configuration,
                HostAppId = "Html5DemoAppCore",
                Storage = new FileStorage(),
                ReportResolver = new ReportTypeResolver()
                                    .AddFallbackResolver(new ReportFileResolver(this.reportsPath)),
            };
        }

        [HttpGet("reportlist")]
        public IEnumerable<string> GetReports()
        {
            return Directory
                .GetFiles(this.reportsPath)
                .Select(path =>
                    Path.GetFileName(path));
        }
        protected override HttpStatusCode SendMailMessage(MailMessage mailMessage)
        {
            throw new System.NotImplementedException("This method should be implemented in order to send mail messages");
            //using (var smtpClient = new SmtpClient("smtp01.mycompany.com", 25))
            //{
            //    smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
            //    smtpClient.EnableSsl = false;

            //    smtpClient.Send(mailMessage);
            //}
            //return HttpStatusCode.OK;
        }
    }
}

In the end, we should create the report viewer. As the HTML5 ASP.NET MVC Report Viewer is a server-side wrapper for the HTML5 JavaScript ReportViewer, it requires a reference to Telerik.ReportViewer.Mvc.dll. However, as this assembly is built against the full .NET Framework, the only possible approach is creating a pure HTML5 Viewer.

Notes

The demo application could be downloaded from here.

See Also

For additional information, you could refer to the new conceptual documentation article .NET Core Support that explains how to use reports in pure .NET Core application for Windows and Linux platforms.

In this article
Not finding the help you need? Improve this article