This is a migrated thread and some comments may be shown as answers.

Custom Data Provider for Reporting

2 Answers 546 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Phil
Top achievements
Rank 1
Phil asked on 03 Jul 2014, 06:23 AM
I am currently testing the trial version of telerik.
I have basic Web based report via WEB API controller that loads a report source.
This report was declared as SQL Data Source.  That works.

However we need to use custom data provider. 
Is there a way of declaring the MetaData and providing a ILIST<Meta> to the report ?

Can the report call a Custom data provider at runtime. ?
Can teh designer call a provider to get meta Data?

I saw a few threads that had similar questions but no obvious answers.

Ideally
A sample in C# with the report engine calling the provider to get Data.  
And how the Report designer is feed the meta data.

Is this possible?
Thanks Phil



2 Answers, 1 is accepted

Sort by
0
Accepted
Stef
Telerik team
answered on 07 Jul 2014, 08:58 AM
Hello Phil,

You can use a data model, which connects to data through your custom data provider. Then use the model in the report via an EntityDataSource, OpenAccessDataSource or the most general ObjectDataSource. All data source components allow you to control the data retrieval with report parameters - Using Parameters with Data Source objects.

To use these data source components in the Standalone Designer, you need to extend the tool's configuration to load the assembly in which the data models is built in.


If you need to change the report's data at run-time you can use a custom report resolver for the Reporting REST service, and apply the changes in the resolver's Resolve method. More details about the suggested approach are available in this forum thread, and example of changing data sources at run-time in the Changing the connection string dynamically according to runtime data KB article.

You can also check the local demos installed by default under C:\Program Files (x86)\Telerik\Reporting Q2 2014\Examples\CSharp.



If you have any further questions, please elaborate on the scenario. Feel free to open a support ticket and send us demo project and additional information in it.

Regards,
Stef
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.

 
0
Phil
Top achievements
Rank 1
answered on 09 Jul 2014, 06:58 AM
// CONFIRMING that it worked.   Thanks.  Code for next person


using System;
using System.Web;
using System.Web.Http.Controllers;
using Telerik.Reporting;
using Telerik.Reporting.Cache.Interfaces;
using Telerik.Reporting.Services.Engine;
using Telerik.Reporting.Services.WebApi;
using CacheFactory = Telerik.Reporting.Services.Engine.CacheFactory;

namespace xyz.Controllers
{

    public class ReportsController : XYZTelerikReportsController{}


    [System.Web.Http.Authorize]
    [BosAPIFilter]
    public class XYZTelerikReportsController : ReportsControllerBase {
        public P42TelerikReportsController() {
            var httpContext = this.RequestContext;

         //   Check auth details...
        }
        protected override IReportResolver CreateReportResolver() {
            return new XYZTelerikReportResolver();
        }

        protected override ICache CreateCache() {
            return Telerik.Reporting.Services.Engine.CacheFactory.CreateFileCache();
        }
    }


    class XYZTelerikReportResolver : Telerik.Reporting.Services.Engine.IReportResolver {
        public ReportSource Resolve(string report) {

            var connectionString = XYZ_FANCYTOOL.GetConnection().ConnectionString;
            var connectionStringHandler = new ReportConnectionStringManager(connectionString);
            var reportsPath = HttpContext.Current.Server.MapPath("~/Reports");
            var sourceReportSource = new UriReportSource { Uri = reportsPath+"/"+report };
            var reportSource = connectionStringHandler.UpdateReportSource(sourceReportSource);


            return reportSource;

        }

         
        

      


    }

    class ReportConnectionStringManager
    {
        readonly string connectionString;

        public ReportConnectionStringManager(string connectionString)
        {
            this.connectionString = connectionString;
        }

        public ReportSource UpdateReportSource(ReportSource sourceReportSource)
        {
            if (sourceReportSource is UriReportSource)
            {
                var uriReportSource = (UriReportSource)sourceReportSource;
                var reportInstance = DeserializeReport(uriReportSource);
                ValidateReportSource(uriReportSource.Uri);
                this.SetConnectionString(reportInstance);
                return CreateInstanceReportSource(reportInstance, uriReportSource);
            }

            if (sourceReportSource is XmlReportSource)
            {
                var xml = (XmlReportSource)sourceReportSource;
                ValidateReportSource(xml.Xml);
                var reportInstance = this.DeserializeReport(xml);
                this.SetConnectionString(reportInstance);
                return CreateInstanceReportSource(reportInstance, xml);
            }

            if (sourceReportSource is InstanceReportSource)
            {
                var instanceReportSource = (InstanceReportSource)sourceReportSource;
                this.SetConnectionString((ReportItemBase)instanceReportSource.ReportDocument);
                return instanceReportSource;
            }

            if (sourceReportSource is TypeReportSource)
            {
                var typeReportSource = (TypeReportSource)sourceReportSource;
                var typeName = typeReportSource.TypeName;
                ValidateReportSource(typeName);
                var reportType = Type.GetType(typeName);
                var reportInstance = (Report)Activator.CreateInstance(reportType);
                this.SetConnectionString((ReportItemBase)reportInstance);
                return CreateInstanceReportSource(reportInstance, typeReportSource);
            }

            throw new NotImplementedException("Handler for the used ReportSource type is not implemented.");
        }

        ReportSource CreateInstanceReportSource(IReportDocument report, ReportSource originalReportSource)
        {
            var instanceReportSource = new InstanceReportSource { ReportDocument = report };
            instanceReportSource.Parameters.AddRange(originalReportSource.Parameters);
            return instanceReportSource;
        }

        void ValidateReportSource(string value)
        {
            if (value.Trim().StartsWith("="))
            {
                throw new InvalidOperationException("Expressions for ReportSource are not supported when changing the connection string dynamically");
            }
        }


        Report DeserializeReport(UriReportSource uriReportSource)
        {
            var settings = new System.Xml.XmlReaderSettings();
            settings.IgnoreWhitespace = true;
            using (var xmlReader = System.Xml.XmlReader.Create(uriReportSource.Uri, settings))
            {
                var xmlSerializer = new Telerik.Reporting.XmlSerialization.ReportXmlSerializer();
                var report = (Telerik.Reporting.Report)xmlSerializer.Deserialize(xmlReader);
                return report;
            }
        }

        Report DeserializeReport(XmlReportSource xmlReportSource)
        {
            var settings = new System.Xml.XmlReaderSettings();
            settings.IgnoreWhitespace = true;
            var textReader = new System.IO.StringReader(xmlReportSource.Xml);
            using (var xmlReader = System.Xml.XmlReader.Create(textReader, settings))
            {
                var xmlSerializer = new Telerik.Reporting.XmlSerialization.ReportXmlSerializer();
                var report = (Telerik.Reporting.Report)xmlSerializer.Deserialize(xmlReader);
                return report;
            }
        }

        void SetConnectionString(ReportItemBase reportItemBase)
        {
            if (reportItemBase.Items.Count < 1)
                return;

            if (reportItemBase is Report)
            {
                var report = (Report)reportItemBase;

                if (report.DataSource is SqlDataSource)
                {
                    var sqlDataSource = (SqlDataSource)report.DataSource;
                    sqlDataSource.ConnectionString = connectionString;
                }
                foreach (var parameter in report.ReportParameters)
                {
                    if (parameter.AvailableValues.DataSource is SqlDataSource)
                    {
                        var sqlDataSource = (SqlDataSource)parameter.AvailableValues.DataSource;
                        sqlDataSource.ConnectionString = connectionString;
                    }
                }
            }

            foreach (var item in reportItemBase.Items)
            {
                //recursively set the connection string to the items from the Items collection
                SetConnectionString(item);

                //set the drillthrough report connection strings
                var drillThroughAction = item.Action as NavigateToReportAction;
                if (null != drillThroughAction)
                {
                    var updatedReportInstance = this.UpdateReportSource(drillThroughAction.ReportSource);
                    drillThroughAction.ReportSource = updatedReportInstance;
                }

                if (item is SubReport)
                {
                    var subReport = (SubReport)item;
                    subReport.ReportSource = this.UpdateReportSource(subReport.ReportSource);
                    continue;
                }

                //Covers all data items(Crosstab, Table, List, Graph, Map and Chart)
                if (item is DataItem)
                {
                    var dataItem = (DataItem)item;
                    if (dataItem.DataSource is SqlDataSource)
                    {
                        var sqlDataSource = (SqlDataSource)dataItem.DataSource;
                        sqlDataSource.ConnectionString = connectionString;
                        continue;
                    }
                }

            }
        }
    }

}
Tags
General Discussions
Asked by
Phil
Top achievements
Rank 1
Answers by
Stef
Telerik team
Phil
Top achievements
Rank 1
Share this question
or