Progress® Telerik® Reporting R3 2017

ReportSource Model Binding

The HTML5 Report Viewer comes with an MVC wrapper that does the JavaScript configuration of the report viewer, where you can type the initial settings of the viewer in C# or VB.NET. The settings include Id, ServiceUrl, templateUrl, client-side ReportSource, and more - HTML5 Report Viewer Initialization.

Important note Important

It is important to know that the MVC project appears as a client for the Reporting RESt Service serving the HTML5 Viewer, even if the service is in the same project. The HTML5 Viewer and Reporting REST Service operate in a client-server model that is not related to the MVC architecture of the project. Modifications in reports and run-time data-bindings can be performed only bythe Reporting REST Service, on the server where the Reporting REST Service is running. For more details, check REST Service Report Resolver.

Getting started

Lets start with the model now. In case all you need is a report viewer that is used to display various reports you can have a simple model to create a strongly typed view - you need to use a client-side report source, like this (TypeReportSource or UriReportSource):

@model Telerik.Reporting.UriReportSource

Then you can use it directly when you are initializing the report viewer:

@(Html.TelerikReporting().ReportViewer()
       .Id("reportViewer1")
       .ServiceUrl("/api/reports/")
       .TemplateUrl("/ReportViewer/templates/telerikReportViewerTemplate.html")
       .ReportSource(Model)
       .ViewMode(ViewMode.Interactive)
       .ScaleMode(ScaleMode.Specific)
       .Scale(1.0)
       .PersistSession(false)
)

Change report viewer according to the report type

Now in case you have a more complex scenario where the report viewer depends on the displayed report you can create a more complex view model that contains your data, including the report source. Lets take as example the scenario where you need to change the template of the report viewer when you are displaying reports that are not suitable for printing. In that case you will have to create two templates for the report viewer - the default one and the one that has no print button. Then you have to create a view model with two properties - the first will contain the uri to the template and the second the report source. Check this snippet:

public class TemplatedReportViewerViewModel
{
    public string TemplateUri { get; set; }
    public UriReportSource ReportSource { get; set; }
}

Once you have the model you should create your own logic to populate it (note that the MVC View is not a suitable place for that logic). Then use the model for your view to make it strongly typed:

@(Html.TelerikReporting().ReportViewer()
       .Id("reportViewer1")
       .ServiceUrl("/api/reports/")
       .TemplateUrl(Model.TemplateUri)
       .ReportSource(Model.ReportSource)
       .ViewMode(ViewMode.Interactive)
       .ScaleMode(ScaleMode.Specific)
       .Scale(1.0)
       .PersistSession(false)
)

Using custom report resolver

There are cases when the supported report sources (Type and Uri) will not be enough. Perhaps you have created a CustomReportResolver in the REST service and since it accepts string as an argument you might also want to directly use a string as your report source. This is possible again through the ReportSource method. The last two overloads of the ReportSource method accept a string as their first argument. This means that the ReportSource can still be strongly typed, but to a string instead of a ReportSource. This gives you the option to implement any custom logic that you need based on that string. For example you could pass the id of the report in the database:

@(Html.TelerikReporting().ReportViewer()
       .Id("reportViewer1")
       .ServiceUrl("/api/reports/")
       .TemplateUrl("/ReportViewer/templates/telerikReportViewerTemplate.html")
       .ReportSource("73")
       .ViewMode(ViewMode.Interactive)
       .ScaleMode(ScaleMode.Specific)
       .Scale(1.0)
       .PersistSession(false)
)

You can also add parameters, like this:

@(Html.TelerikReporting().ReportViewer()
       .Id("reportViewer1")
       .ServiceUrl("/api/reports/")
       .TemplateUrl("/ReportViewer/templates/telerikReportViewerTemplate.html")
       .ReportSource("73", new Dictionary<string, object>() { { "parameter1", "value1" }, { "parameter2", "value2" } })
       .ViewMode(ViewMode.Interactive)
       .ScaleMode(ScaleMode.Specific)
       .Scale(1.0)
       .PersistSession(false)
)

The view can also be strongly typed:

@(Html.TelerikReporting().ReportViewer()
       .Id("reportViewer1")
       .ServiceUrl("/api/reports/")
       .TemplateUrl("/ReportViewer/templates/telerikReportViewerTemplate.html")
       .ReportSource(Model.ReportSource, Model.Parameters)
       .ViewMode(ViewMode.Interactive)
       .ScaleMode(ScaleMode.Specific)
       .Scale(1.0)
       .PersistSession(false)
)

Finally on the server side your custom report resolver can implement the custom logic that will take in consideration the id and create a report source as per your needs:

class ModelBindingReportResolver : Telerik.Reporting.Services.Engine.IReportResolver
{
    public Telerik.Reporting.ReportSource Resolve(string reportId)
    {
        var report = new Invoice();
        if (true) // condition here
        {
            // prepare your report here
        }
        else
        {
            // do something else with report here
        }

        return new Telerik.Reporting.InstanceReportSource { ReportDocument = report };
    }
}