I'm currently working on a ASP.NET MVC application in which we recently start integrating with Telerik Report.
I designed the report as shown in report-design.png. I fed the object datasource at runtime and it works just fine with the following code. And it shows in view as in report-view.png.
/// <summary>
/// Summary description for Report2.
/// </summary>
public partial class TelerikQuoteReport : Telerik.Reporting.Report
{
public TelerikQuoteReport() //WISH IT TO ACCEPT PARAMETER LIKE ID
{
InitializeComponent();
var appCon = new AppContext(new DbContext());
var rep = new OperationalDocumentRepository(appCon);
//WISH TO REPLACE THE ID WITH PARAMETER SO I CAN REUSE THE REPORT WITH DIFFERENT DATA
this.DataSource = new List<ODQuote>() { rep.GetDocument<ODQuote>(new Guid("968e62ac-b295-4fd1-b93b-7fdc99d03093")) };
}
}
Except now I want to dynamically feed the ID so I can reuse the report with different data. I tried the following approach and tried to feed a parameter to the report constructor, but without any luck.
$(document).ready(function () {
$("#reportViewer1").telerik_ReportViewer({
serviceUrl: "/api/reports",
templateUrl: "/ReportViewer/templates/telerikReportViewerTemplate-8.1.14.804.html",
reportSource: {
report: "TelerikReports.TelerikQuoteReport, TelerikReports",
parameters: { Id: '@ViewData["Id"]' }
},
viewMode: telerikReportViewer.ViewModes.INTERACTIVE,
scaleMode: telerikReportViewer.ScaleModes.SPECIFIC,
scale: 1.0,
ready: function () {
//this.refreshReport();
}
});
});
So my question is in the case of using object datasource in reports, how could we dynamically change the datasource so we can use the same report template with the same "type" of data which is essentially replacing with different instances.
Thank you.
12 Answers, 1 is accepted
The recommended approach is to pass the ID to a report parameter:
parameters: { Id:
'@ViewData["Id"]'
}
and then in the report definition pass the parameter value to an ObjectDataSource component parameter.
For more details on this approach, please refer to the Using Parameters with the ObjectDataSource Component help article.
Regards,
Nasko
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
Thank you for your reply. However,as you can see from my code in the initial post. I locked the parameter in view using:
reportSource: {
report: "TelerikReports.TelerikQuoteReport, TelerikReports",
parameters: { Id: '@ViewData["Id"]' }
},
And on the server side, I want to access the Id parameter as followeed
public
TelerikQuoteReport()
{
InitializeComponent();
}
private
void
TelerikQuoteReport_NeedDataSource(
object
sender, EventArgs e)
{
Telerik.Reporting.Processing.Report report = (Telerik.Reporting.Processing.Report)sender;
var test = report.Parameters["Id"].Value;
}
Result is I could not see the parameter Id, how could I pass parameter from view to server side this way?
Hi Rui,
Please provide code base or pic of above resolved issue.
I have a view in which i need to generate report based on selected "id", i passed id as parameter from the view and need to get the value of id in report.cs and then need to pass it in select method of object data source. So i need a report that display record based on singly id.
please find attached images with highlighted code.
please resolve it.
Thanks,
Mohan
Hi Mohan,
The way that works for me is as followed.
The part that supplies parameters is similar as in your screenshot. I used ViewData to provide dynamic data. You only need to supply parameters you want (I guess parameter case may matter, in your case would be "ID") and rely on the report framework to bind them to your data retrieving method. If you debug your host application and break at the data retrieving method you should see parameters coming through. Hope this can help you.
01.
// Report action to show report for a document
02.
public
ActionResult Report(Guid docid)
03.
{
04.
TempData[
"parameters"
] =
new
Dictionary<String, String>() { {
"id"
, doc.Id.ToString() }, {
"user"
, AppContext.Identity.Id.ToString() } };
05.
return
RedirectToAction(
"Index"
,
"ReportViewer"
,
new
06.
{
07.
name = GetReportName(),
08.
backurl = Url.Action(
"Id"
, GetViewFolderName(),
new
{ Id = docid })
09.
});
10.
}
11.
12.
// Unified hub action for rendering report
13.
public
ActionResult Index(
string
name,
string
backurl)
14.
{
15.
// Code omitted for simplicity
16.
if
(TempData.ContainsKey(
"parameters"
))
17.
ViewData[
"parameters"
] = TempData[
"parameters"
];
18.
return
View();
19.
}
20.
21.
// Report html viewer
22.
parameters: {
23.
@
if
(ViewData[
"parameters"
] !=
null
)
24.
{
25.
foreach
(KeyValuePair<
string
,
string
> param
in
ViewData[
"parameters"
]
as
Dictionary<
string
,
string
>)
26.
{
27.
@(param.Key)<text>:
'</text>@(param.Value)<text>'
,</text>
28.
}
29.
}
30.
}
31.
32.
// Object datasource member method for retrieving data
33.
public
TView GetByDisplayId(
string
id,
string
user)
34.
{
35.
// Code omitted for simplicity
36.
// Parameter id and user would be bound by Telerik report framework,
37.
// You should be able to access them here and render the data you want
38.
}
I have a similar question.
I need to get the real report parameter value in Report's constructor (not NeedDataSource event)
for "Create Report Items Programmatically" purpose.
https://docs.telerik.com/reporting/programmatic-creating-controls
public TelerikQuoteReport()
{
InitializeComponent();
... get real parameter of report here ...
... Create Report Items Programmatically here ...
}
Pass values to report parameters via Telerik.Reporting.TypeReportSource :
.cshtml
@(Html.TelerikReporting().ReportViewer()
...
.ReportSource(NewTypeReportSource)
...
...
...)
Is there have any solution ?
Best regards
Chris
... get real parameter of report here ...
->
... get real value of parameter of report here ...
Try handling the ItemDataBinding event of the Report itself. You will have access to the report parameter evaluated values thru:
//Take the Telerik.Reporting.Processing.Report instance
Telerik.Reporting.Processing.Report report = (Telerik.Reporting.Processing.Report)sender;
var x = report.Parameters[
"ManagerID"
].Value;
In this event handler, it is still safe to modify the report definition. Hope this helps.
Regards,
Milen
Progress Telerik
HI
I know there have a way for modify the field of the report (ItemDataBinding event),
but my request is get real value of parameter of report then
"Create Report Items Programmatically".
There maybe have no any soluton for that request (because of InstanceReportSource obsoleted).
I will render the report to pdf on the fly and return the file bytes (FileContentResult).
Best regards
Chris
In the Report item ItemDataBinding event you may take the real processing values of the Report Parameters, e.g. as passed from the viewer. You may then modify/add report processing items (i.e. from Telerik.Reporting.Processing namespace) to the report, and this will be reflected in the generated reporting document. For details you may see the Changes on items in report events are not applied KB article.
Indeed we do *not* recommend to use the InstanceReportSource. It is the only way to pass an instance of report to the Reporting engine, hence it can be used in case it is absolutely necessary to modify report definition run time.
Regards,
Todor
Progress Telerik
HI
Yes, I could get the report parameters correctly :
private void IpoQ010Report_ItemDataBinding(object sender, EventArgs e)
{
Telerik.Reporting.Processing.Report NewReport = (Telerik.Reporting.Processing.Report)sender;
... NewReport.Parameters ...
But still don't know how to create report item dynamically :
-Compile syntax error :
Telerik.Reporting.Processing.TextBox textbox = new Telerik.Reporting.Processing.TextBox();
-> Error CS1729 'TextBox' does not contain a constructor that takes 1 arguments.
.TextBox not added :
private void IpoQ010Report_ItemDataBinding(object sender, EventArgs e)
{
Telerik.Reporting.Processing.Report NewReport = (Telerik.Reporting.Processing.Report)sender;
Telerik.Reporting.Processing.PageSection NewPageHeader = NewReport.PageHeader;
Telerik.Reporting.TextBox NewTextBox;
//
NewTextBox = new Telerik.Reporting.TextBox();
NewTextBox.Location = new PointU(new Point(0, 0));
NewTextBox.Width = new Unit(10, UnitType.Cm);
NewTextBox.Height = new Unit(2, UnitType.Cm);
NewTextBox.Value = "GG1";
NewPageHeader.ItemDefinition.Items.AddRange(new Telerik.Reporting.ReportItemBase[] { NewTextBox
*There have no any official demo about this.
Best regards
Chris
The Processing items are intended to be created by our code only and their constructors are Internal. Therefore, processing items cannot be created in the Report events as the reports would be defined in another assembly.
We do not recommend to modify the report layout run time. Therefore, we do no provide examples on this. However, we have provided this option - you may modify the existing processing items in the NeedDataSource and ItemDataBinding events. We cannot guarantee that this approach will work in the same way with future versions of the product.
When adding definition items in a Report event it is usually late and the new items may not be considered in the rendered report document. You may modify report definition by instantiating it and for example adding new items. Then the modified report instance should be passed to the Report Viewer or ReportProcessor wrapped in an InstanceReportSource.
Regards,
Todor
Progress Telerik