This tutorial teaches you how to get reports from a Telerik Reporting REST Service and have them display in ASP.NET Core applications.
This blog post demonstrates how to embed the Telerik HTML5 Report Viewer (or viewer for short) and host the Telerik Reporting REST Service (or service for short) in your ASP.NET Core 3+ web application. Here are the topics I am going to cover as we discuss .NET reporting:
The viewer's purpose is to display report documents on a web page. Under the hood, the viewer is a custom jQuery-based widget. Widgets are feature-rich, stateful plugins that have a full life cycle, along with methods and events. The layout of the viewer is stored in an HTML template that supports mobile and desktop browsers and is fully customizable. Similar to Kendo UI widgets the viewer's default HTML template supports predefined themes and custom themes.
Grab the eBook: A Quick Guide to Expert .NET Reporting Tools
I mentioned that the viewer displays report documents. A report document, however, is the output of the Report Engine.
The viewer cannot do the processing and rendering work by itself and this is where the Reporting REST Service comes in. The service wraps the Report Engine and exposes its functionality over HTTP, so the viewer can access it. A common scenario for the viewer-service interaction described in a high-level of abstraction would be:
For convenience, the service can also provide all the required HTML5 Report Viewer widget resources - JavaScript, CSS, and HTML template files.
As the viewer cannot function without the service, let's review the steps to host the service first. For this post, I'll assume that the project displaying reports is also the service project. That way I don't have to configure Cross-Origin Resource Sharing (CORS). However, if you need to use separate projects in your solution, here is a very good article that explains how to enable CORS in ASP.NET Core.
If you don't have an existing ASP.NET Core web application, follow these steps to create one:
To host the Reporting REST Service in this project or another existing project, add the NuGet package Telerik.Reporting.Services.AspNetCore from the Telerik NuGet feed at https://nuget.telerik.com/nuget.
The service package will add its own dependencies to the project, such as Microsoft.AspNet.Core.Mvc.NewtonsoftJson. To activate the NewtonsoftJson package dependency, open Startup.cs and change the services.AddRazorPages line in the ConfigureServices method to:
services.AddRazorPages().AddNewtonsoftJson();
Right below this line add the configuration code for a minimal Reporting REST Service implementation (add appropriate usings as well):
services.TryAddSingleton<IReportServiceConfiguration>(
sp =>
new
ReportServiceConfiguration
{
Storage =
new
FileStorage(),
ReportSourceResolver =
new
UriReportSourceResolver(
System.IO.Path.Combine(
sp.GetService<IWebHostEnvironment>().ContentRootPath,
"Reports"
))
});
The Storage configuration above specifies that the service will save its internal state objects and temp files on the file system. Other storage options are also available.
The ReportSourceResolver option instructs the service to search for report definition files inside the Reports application folder. For more ways to resolve a report identifier to a specific report definition, check the complete REST Service Report Source Resolver reference.
The Reports folder does not exist yet, but you'll create it in a moment since you'll need to add report definition files there. I grabbed my report definition (Report Catalog.trdp) from the Telerik Reporting installation folder - C:\Program Files (x86)\Progress\Telerik Reporting R2 2020\Report Designer\Examples, but you can create a new one using the Standalone Report Designer. Once you have a report definition, you need to add it to your project:
Also inside the ConfigureServices method, make sure the application is configured for API controllers by adding:
services.AddControllers();
And map those controller endpoints by adding the following line (endpoints.MapControllers();
) to the Configure method:
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
The next step is to create the actual ReportsController class which is the essence of the service:
Change the content of the new controller to:
using
Microsoft.AspNetCore.Mvc;
using
Telerik.Reporting.Services;
using
Telerik.Reporting.Services.AspNetCore;
namespace
AspNetCoreReportViewerSample.Controllers
{
[Route(
"api/reports"
)]
public
class
ReportsController : ReportsControllerBase
{
public
ReportsController(IReportServiceConfiguration reportServiceConfiguration)
:
base
(reportServiceConfiguration)
{
}
}
}
The string api/reports inside the Route attribute maps the URL that will be used to access this controller. The service is now ready and waiting to serve your reports.
There is a variety of other configuration options, including how to use a configuration file with connection strings, and more. To delve deeper into the topic, visit the complete reference to setting up a Reporting REST Service.
With the Web Application project template that I chose earlier my application's landing page is Pages/Index.cshtml. This page uses a common layout stored in Pages/Shared/_Layout.cshtml. The common layout has a reference to jQuery by default. If your application does not reference jQuery yet, you can link it from the jQuery CDN.
To have a neat organization of the common layout page, add a custom section to the head element of _Layout.cshtml which you'll use later to add the viewer's Kendo UI themes:
<
head
>
...
@RenderSection("Head", required: false)
</
head
>
Inside Pages/Index.cshtml you need a div element to hold the viewer. This element should have a unique id attribute value, which will be later used in the viewer's JavaScript. It is also required to set the div element's dimensions via CSS file or inline style, or the viewer will not be visible on the page:
<
div
id
=
"reportViewer1"
style
=
"width:940px; height:1300px"
>
</
div
>
Add links to the desired Kendo UI theme in the custom Head section prepared earlier:
@section Head {
<
link
href
=
"https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.common.min.css"
rel
=
"stylesheet"
/>
<
link
href
=
"https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.default.min.css"
rel
=
"stylesheet"
/>
}
Finally, add a link to the viewer widget's JavaScript file inside a Scripts section and call the telerik_ReportViewer method.
The Scripts section will help insert the viewer script after the reference to jQuery inside the common layout file. The viewer will then be able to find its jQuery dependency and extend the global jQuery object instance with the telerik_ReportViewer method.
telerik_ReportViewer is a jQuery extension method that creates and configures the viewer object. In this example, the viewer object is created inside the #reportViewer1 div element. The serviceUrl matches the URL of the ReportsController route and the report option value is the file name of the report definition:
@section Scripts {
<script src=
"/api/reports/resources/js/telerikReportViewer"
></script>
<script type=
"text/javascript"
>
$(document).ready(
function
() {
$(
"#reportViewer1"
)
.telerik_ReportViewer({
serviceUrl:
"api/reports"
,
reportSource: {
report:
"Report Catalog.trdp"
},
scaleMode: telerikReportViewer.ScaleModes.SPECIFIC,
scale: 1.0
});
});
</script>
}
Above is the minimum required configuration of the viewer object. For a full list of configuration options, methods, and events, head to the HTML5 Report Viewer documentation.
This is how the final Index.cshtml looks:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
@section Head {
<
link
href
=
"https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.common.min.css"
rel
=
"stylesheet"
/>
<
link
href
=
"https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.default.min.css"
rel
=
"stylesheet"
/>
}
<
div
class
=
"text-center"
>
<
div
id
=
"reportViewer1"
style
=
"width:940px; height:1300px"
>
</
div
>
</
div
>
@section Scripts {
<
script
src
=
"/api/reports/resources/js/telerikReportViewer"
></
script
>
<
script
type
=
"text/javascript"
>
$(document).ready(function () {
$("#reportViewer1")
.telerik_ReportViewer({
serviceUrl: "api/reports",
reportSource: {
report: "Report Catalog.trdp"
},
scaleMode: telerikReportViewer.ScaleModes.SPECIFIC,
scale: 1.0
});
});
</
script
>
}
What's left is to press F5 in Visual Studio and watch how the HTML5 Report Viewer will request the Report Catalog.trdp report from the service. The service will instruct the Report Engine to render the report definition in HTML5 format and return it to the viewer as a report document. If all goes as expected, you'll find yourself looking at a similar screen:
If you run into any problems, press F12 to check for errors in the browser console and log the network traffic using Fiddler. All this information will be incredibly valuable if you decide to contact our legendary support team.
You can download the sample application from the telerik/reporting-samples GitHub repository.
You can choose Telerik Reporting and Telerik Report Server as individual products or enjoy them as part of the great Telerik DevCraft bundles.
Telerik DevCraft is the finest software developer tools collection across .NET and JavaScript technologies, which includes modern, feature-rich and professionally designed UI components for web, desktop and mobile applications, reporting and report management solutions, document processing libraries, automated testing and mocking tools from the Telerik and Kendo UI suites. DevCraft will arm you with everything you need to deliver outstanding applications in less time and with less effort. With the backing of our legendary support team, which consists of the developers who build the products, and a ton of resources and trainings you can rest assured that you have a stable partner to rely on for your everyday challenges along your software development journey.
Atanas Keranov was a Software Engineer in the Telerik Reporting division.