ReportSource Model Binding Overview
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.
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 operates 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 by the Reporting REST Service, on the server where the Reporting REST Service is running. For more details, check REST Service Report Source Resolver.
Getting started
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
@ModelType 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)
)
@Code
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)
End Code
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. Let's take as an 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; }
}
Public Class TemplatedReportViewerViewModel
Public Property TemplateUri() As String
Public Property ReportSource() As UriReportSource
End Class
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)
)
@Code
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)
End Code
Using custom IReportSourceResolver
There are cases when the supported report sources (Type
and Uri
) will not be enough. Perhaps you have created a custom implementation of the IReportSourceResolver interface in the REST service and since it accepts a 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)
)
@Code
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)
End Code
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)
)
@Code
Html.TelerikReporting().ReportViewer() _
.Id("reportViewer1") _
.ServiceUrl("/api/reports/") _
.TemplateUrl("/ReportViewer/templates/telerikReportViewerTemplate.html") _
.ReportSource("73", New Dictionary(Of String, Object)() From {{"parameter1", "value1"}, {"parameter2", "value2"}}) _
.ViewMode(ViewMode.Interactive) _
.ScaleMode(ScaleMode.Specific) _
.Scale(1.0) _
.PersistSession(False)
End Code
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)
)
@Code
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)
End Code
Finally, on the server side, your custom report source resolver can implement the custom logic that will take into consideration the ID and create a report source as per your needs:
class ModelBindingReportSourceResolver : IReportSourceResolver
{
public Telerik.Reporting.ReportSource Resolve(string reportId, OperationOrigin operationOrigin, IDictionary<string, object> currentParameterValues)
{
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 };
}
}
Class ModelBindingReportSourceResolver
Implements IReportSourceResolver
Public Function Resolve(reportId As String, operationOrigin As OperationOrigin, currentParameterValues As IDictionary(Of String, Object)) As Telerik.Reporting.ReportSource Implements Telerik.Reporting.Services.IReportSourceResolver.Resolve
Dim report = New Invoice() ' prepare your report here
If True Then ' condition here
' do something else with report here
Else
End If
Return New Telerik.Reporting.InstanceReportSource() With {
.ReportDocument = report
}
End Function
End Class