Error path SubReport

3 posts, 0 answers
  1. Paulo Rogério
    Paulo Rogério avatar
    4 posts
    Member since:
    May 2014

    Posted 18 Aug Link to this post

    I need to open a report that has subreports, so far managed to do.

    Came the need to change the connection of the run-time report and then follow the articles of you I implemented an object that changes the connection string, but my subreport always gets the wrong path, that is, the main report opens but the subreport has problem in the path of the file in the same directory. I've tried to solve the path of the subreport and did not succeed, can anyone help me?

    Below is my code:
    Code my view 

    01.@model Samich.Relatorios.ViewModels.SGO.RelAdvertenciaMotoristaViewModel
    02.     
    03.@{
    04.    Layout = null;
    05.}
    06.<!DOCTYPE html>
    08.<head>
    09.    <title>Telerik MVC HTML5 Report Viewer</title>
    10. 
    11.    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    12. 
    13.    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
    14. 
    15.    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    16. 
    19. 
    20.    <!--kendo.web.min.js or kendo.all.min.js can be used as well instead of the following custom Kendo UI-->
    21.    <script src="@Url.Content("~/ReportViewer/js/kendo.subset.2015.3.930.min.js")"></script>
    22. 
    23.    <style>
    24.        #reportViewer1 {
    25.            position: relative;
    26.            width: 1300px;
    27.            height: 900px;
    28.            font-family: Verdana, Arial;
    29.        }
    30.    </style>
    31. 
    32.    <script src="@Url.Content("~/ReportViewer/js/telerikReportViewer-10.1.16.615.min.js")"></script>
    33. 
    34.</head>
    35.<body>
    36. 
    37.    @{
    38.        Dictionary<string, object> parametros = new Dictionary<string, object>();
    39.        parametros.Add("DataOcorrencia", Model.DataOcorrencia);
    40.    }
    41. 
    42.    @(Html.TelerikReporting().ReportViewer()
    43.        .Id("reportViewer1")
    44.        .ServiceUrl(Url.Content("/api/reports"))
    45.        //.ReportSource("_SGO_Relatorio_Ocorrencia_Monitoramento.trdp", parametros)
    46.        .ReportSource("_SGO_Relatorio_Ocorrencia_Monitoramento.trdx", parametros)
    47.        //.ReportSource("_SGO_Relatorio_Ocorrencia_Monitoramento.trdx")
    48.        //.ReportSource(Model.ReportSource)
    49. 
    50.        .ViewMode(ViewMode.PrintPreview)
    51.        .ScaleMode(ScaleMode.FitPageWidth)
    52.        .Scale(1.0)
    53.        .PersistSession(false)
    54.        .PrintMode(PrintMode.AutoSelect)
    55.    )
    56. 
    57.</body>
    58. 
    59. 
    60. 
    61. 
    62. 
    63. 
    64. 
    65. 
    66. 
    67. 
    68. 
    69. 
    70. 
    71. 
    72. 
    73. 
    74. 
    75.</html>

    Code my controller RelAdvertenciaMotorista

    01.using System;
    02.using System.Web.Mvc;
    03.using Samich.Relatorios.ViewModels.SGO;
    04.using Samich.Relatorios.Helpers;
    05.using Telerik.Reporting;
    06.using System.Collections.Generic;
    07.using System.IO;
    08.using Telerik.Reporting.Services.WebApi;
    09.using Telerik.Reporting.Services;
    10.using Telerik.Reporting.Cache.File;
    11.using System.Collections.ObjectModel;
    12. 
    13.namespace Samich.Relatorios.Controllers.SGO
    14.{
    15.    public class RelAdvertenciaMotoristaController : Controller
    16.    {
    17.        public ActionResult GerarRelatorio()
    18.        {
    19.            
    20. 
    21.            ////Crio e populo a ViewModel com os dados do novo relatório
    22.            RelAdvertenciaMotoristaViewModel vm = new RelAdvertenciaMotoristaViewModel();
    23.            vm.DataOcorrencia = DateTime.Now;
    24.            //vm.ReportSource = reportSource;
    25. 
    26.            //Chamo a ViewModel que contém o relatório
    27.            return View("../SGO/RelAdvertenciaMotorista/GerarRelatorio", vm);
    28.        }
    29.    }
    30.}


    Code my class ReportConnectionStringManager

    001.using System;
    002.using System.Linq;
    003.using Telerik.Reporting;
    004. 
    005.namespace Samich.Relatorios.Helpers
    006.{
    007.    public class ReportConnectionStringManager
    008.    {
    009.        readonly string connectionString;
    010. 
    011.        public ReportConnectionStringManager(string connectionString)
    012.        {
    013.            this.connectionString = connectionString;
    014.        }
    015. 
    016.        public ReportSource UpdateReportSource(ReportSource sourceReportSource)
    017.        {
    018.            if (sourceReportSource is UriReportSource)
    019.            {
    020.                var uriReportSource = (UriReportSource)sourceReportSource;
    021. 
    022.                //Monto o caminho do arquivo aqui, pois podem existir subreports no relatório e
    023.                //a rotina pega os mesmos dinamicamente
    024.                if (!uriReportSource.Uri.Contains(@"\Reports\"))
    025.                {
    026.                    uriReportSource.Uri = System.Web.HttpContext.Current.Server.MapPath(@"~/Reports/" + uriReportSource.Uri);
    027.                     
    028.                }
    029.                 
    030. 
    031.                var reportInstance = DeserializeReport(uriReportSource);
    032.                ValidateReportSource(uriReportSource.Uri);
    033.                this.SetConnectionString(reportInstance);
    034. 
    035.                return CreateInstanceReportSource(reportInstance, uriReportSource);
    036.            }
    037. 
    038.            if (sourceReportSource is XmlReportSource)
    039.            {
    040.                var xml = (XmlReportSource)sourceReportSource;
    041.                ValidateReportSource(xml.Xml);
    042.                var reportInstance = this.DeserializeReport(xml);
    043.                this.SetConnectionString(reportInstance);
    044.                return CreateInstanceReportSource(reportInstance, xml);
    045.            }
    046. 
    047.            if (sourceReportSource is InstanceReportSource)
    048.            {
    049.                var instanceReportSource = (InstanceReportSource)sourceReportSource;
    050.                this.SetConnectionString((ReportItemBase)instanceReportSource.ReportDocument);
    051.                return instanceReportSource;
    052.            }
    053. 
    054.            if (sourceReportSource is TypeReportSource)
    055.            {
    056.                var typeReportSource = (TypeReportSource)sourceReportSource;
    057.                var typeName = typeReportSource.TypeName;
    058.                ValidateReportSource(typeName);
    059.                var reportType = Type.GetType(typeName);
    060.                var reportInstance = (Report)Activator.CreateInstance(reportType);
    061.                this.SetConnectionString((ReportItemBase)reportInstance);
    062.                return CreateInstanceReportSource(reportInstance, typeReportSource);
    063.            }
    064. 
    065.            throw new NotImplementedException("Handler for the used ReportSource type is not implemented.");
    066.        }
    067. 
    068.        ReportSource CreateInstanceReportSource(IReportDocument report, ReportSource originalReportSource)
    069.        {
    070.            var instanceReportSource = new InstanceReportSource { ReportDocument = report };
    071.            instanceReportSource.Parameters.AddRange(originalReportSource.Parameters);
    072.            return instanceReportSource;
    073.        }
    074. 
    075.        void ValidateReportSource(string value)
    076.        {
    077.            if (value.Trim().StartsWith("="))
    078.            {
    079.                throw new InvalidOperationException("Expressions for ReportSource are not supported when changing the connection string dynamically");
    080.            }
    081.        }
    082. 
    083. 
    084.        public Report DeserializeReport(UriReportSource uriReportSource)
    085.        {
    086.            var settings = new System.Xml.XmlReaderSettings();
    087.            settings.IgnoreWhitespace = true;
    088. 
    089.            //Monto o caminho do arquivo aqui, pois podem existir subreports no relatório e
    090.            //a rotina pega os mesmos dinamicamente
    091.            if (!uriReportSource.Uri.Contains(@"\Reports\"))
    092.            {
    093.                uriReportSource.Uri = System.Web.HttpContext.Current.Server.MapPath(@"~/Reports/" + uriReportSource.Uri);
    094.            }
    095. 
    096.            using (var xmlReader = System.Xml.XmlReader.Create(uriReportSource.Uri, settings))
    097.            {
    098.                var xmlSerializer = new Telerik.Reporting.XmlSerialization.ReportXmlSerializer();
    099.                var report = (Telerik.Reporting.Report)xmlSerializer.Deserialize(xmlReader);
    100.                return report;
    101.            }
    102.        }
    103. 
    104.        Report DeserializeReport(XmlReportSource xmlReportSource)
    105.        {
    106.            var settings = new System.Xml.XmlReaderSettings();
    107.            settings.IgnoreWhitespace = true;
    108.            var textReader = new System.IO.StringReader(xmlReportSource.Xml);
    109.            using (var xmlReader = System.Xml.XmlReader.Create(textReader, settings))
    110.            {
    111.                var xmlSerializer = new Telerik.Reporting.XmlSerialization.ReportXmlSerializer();
    112.                var report = (Telerik.Reporting.Report)xmlSerializer.Deserialize(xmlReader);
    113.                return report;
    114.            }
    115.        }
    116. 
    117.        void SetConnectionString(ReportItemBase reportItemBase)
    118.        {
    119.            if (reportItemBase.Items.Count < 1)
    120.                return;
    121. 
    122.            if (reportItemBase is Report)
    123.            {
    124.                var report = (Report)reportItemBase;
    125. 
    126. 
    127.                if (report.DataSource is SqlDataSource)
    128.                {
    129.                    var sqlDataSource = (SqlDataSource)report.DataSource;
    130.                    sqlDataSource.ConnectionString = connectionString;
    131.                }
    132.                foreach (var parameter in report.ReportParameters)
    133.                {
    134.                    if (parameter.AvailableValues.DataSource is SqlDataSource)
    135.                    {
    136.                        var sqlDataSource = (SqlDataSource)parameter.AvailableValues.DataSource;
    137.                        sqlDataSource.ConnectionString = connectionString;
    138.                    }
    139.                }
    140.            }
    141. 
    142.            foreach (var item in reportItemBase.Items)
    143.            {
    144.                //recursively set the connection string to the items from the Items collection
    145.                SetConnectionString(item);
    146. 
    147.                //set the drillthrough report connection strings
    148.                var drillThroughAction = item.Action as NavigateToReportAction;
    149.                if (null != drillThroughAction)
    150.                {
    151.                    var updatedReportInstance = this.UpdateReportSource(drillThroughAction.ReportSource);
    152.                    drillThroughAction.ReportSource = updatedReportInstance;
    153.                }
    154. 
    155.                if (item is SubReport)
    156.                {
    157.                    var subReport = (SubReport)item;
    158. 
    159.                     
    160. 
    161.                    //UriReportSource uri = new UriReportSource() { Uri = System.Web.HttpContext.Current.Server.MapPath(@"~/Reports/SGO_Ocorrencias.trdx") };
    162.                    //subReport.ReportSource = uri;
    163. 
    164.                    subReport.ReportSource = this.UpdateReportSource(subReport.ReportSource);
    165.                    continue;
    166.                }
    167. 
    168.                //if (item is DetailSection)
    169.                //{
    170.                //    //Seta o uri paulo
    171.                //    var detailSectionItem = (DetailSection)item;
    172. 
    173.                //    detailSectionItem.Items.ToList().ForEach(x => {
    174.                //        if (x is SubReport)
    175.                //        {
    176.                //            var subReportX = (SubReport)x;
    177. 
    178.                //            string nameReport = ((ReportItemBase)(((InstanceReportSource)subReportX.ReportSource).ReportDocument)).Name;
    179.                //            var uriItem = new UriReportSource() { Uri = nameReport + ".trdx" };
    180. 
    181.                //            if (!uriItem.Uri.Contains(@"\Reports\"))
    182.                //            {
    183.                //                uriItem.Uri = System.Web.HttpContext.Current.Server.MapPath(@"~/Reports/" + uriItem.Uri);
    184.                //            }
    185. 
    186.                //            subReportX.ReportSource = uriItem;
    187.                //        }
    188.                //    });
    189.                //}
    190. 
    191. 
    192.                //Covers all data items(Crosstab, Table, List, Graph, Map and Chart)
    193.                if (item is DataItem)
    194.                {
    195.                    var dataItem = (DataItem)item;
    196.                    if (dataItem.DataSource is SqlDataSource)
    197.                    {
    198.                        var sqlDataSource = (SqlDataSource)dataItem.DataSource;
    199.                        sqlDataSource.ConnectionString = connectionString;
    200.                        continue;
    201.                    }
    202.                }
    203. 
    204.            }
    205.        }
    206.    }
    207.}

    Code my class MyResolver
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Text;
    05.using System.Threading.Tasks;
    06.using Telerik.Reporting;
    07.using Telerik.Reporting.Services.Engine;
    08. 
    09.namespace Samich.Relatorios.Helpers
    10.{
    11.    public class MyResolver : IReportResolver
    12.    {
    13.        public Telerik.Reporting.ReportSource Resolve(string report)
    14.        {
    15.            Report reportInstance = null;
    16.             
    17.            //Obtenho a string de conexão que irei usar para o relatório.
    18.            var stringConexao = System.Configuration.ConfigurationManager.ConnectionStrings["LinaveConnectionString"].ConnectionString;
    19. 
    20.            //retrieve an instance of the report     
    21.            var uriReportSource = new UriReportSource { Uri = report };
    22. 
    23.            //Passo a string de conexão para a classe ReportConnectionStringManager que será
    24.            //responsável por alterar todas as conexões de dentro do relatório
    25.            var newReport = new ReportConnectionStringManager(stringConexao);
    26.             
    27.            //retrieve an instance of the report     
    28.            reportInstance = newReport.DeserializeReport(uriReportSource);
    29. 
    30.            //Atualizo o relatório com a nova conexão
    31.            var reportSource = newReport.UpdateReportSource(uriReportSource);
    32. 
    33.            //change the report's DataSource settings
    34.            (reportInstance.DataSource as Telerik.Reporting.SqlDataSource).ConnectionString = stringConexao;
    35. 
    36.                //change a nested data item's DataSource
    37.                //((reportInstance.Items.Find("table1", true)[0] as Telerik.Reporting.Table).DataSource = GetStoredOnTheServerData();
    38.                //set report parameters values
    39.                //reportInstance.ReportParameters["UserId"].Value = GetUserId();
    40.            //}
    41.            return new InstanceReportSource { ReportDocument = reportInstance };
    42.        }
    43. 
    44.         
    45.    }
    46.}

    Code my ReportController

    01.namespace Samich.Relatorios.Controllers
    02.{
    03.    using Helpers;
    04.    using System.IO;
    05.    using System.Net.Http;
    06.    using System.Web;
    07.    using System.Web.Http;
    08.    using Telerik.Reporting.Cache.File;
    09.    using Telerik.Reporting.Services;
    10.    using Telerik.Reporting.Services.WebApi;
    11. 
    12.    //The class name determines the service URL.
    13.    //ReportsController class name defines /api/report/ service URL.
    14.    public class ReportsController : ReportsControllerBase
    15.    {
    16.        static ReportServiceConfiguration configurationInstance;
    17. 
    18.        static ReportsController()
    19.        {
    20.            //This is the folder that contains the report definitions
    21.            //In this case this is the Reports folder
    22.            var appPath = HttpContext.Current.Server.MapPath("~/");
    23.            var reportsPath = Path.Combine(appPath, "Reports");
    24.             
    25.            //Add resolver for trdx/trdp report definitions,
    26.            //then add resolver for class report definitions as fallback resolver;
    27.            //finally create the resolver and use it in the ReportServiceConfiguration instance.
    28.            //var resolver = new ReportFileResolver(reportsPath)
    29.            //    .AddFallbackResolver(new ReportTypeResolver());
    30. 
    31.            //Setup the ReportServiceConfiguration
    32.            configurationInstance = new ReportServiceConfiguration
    33.            {
    34.                HostAppId = "Html5App",
    35.                Storage = new FileStorage(),
    36.                ReportResolver = new MyResolver(),
    37.                //ReportResolver = resolver
    38.                // ReportSharingTimeout = 0,
    39.                // ClientSessionTimeout = 15,
    40.            };
    41.        }
    42. 
    43.        public ReportsController()
    44.        {
    45.            //Initialize the service configuration
    46.            this.ReportServiceConfiguration = configurationInstance;
    47.        }
    48.    }
    49.}     

  2. Paulo Rogério
    Paulo Rogério avatar
    4 posts
    Member since:
    May 2014

    Posted 18 Aug in reply to Paulo Rogério Link to this post

    Do you have any sample project to change the report connection string and that it have a subreport within?

    My reports are inside a folder called Reports, plus the subreport is not found
  3. DevCraft banner
  4. Katia
    Admin
    Katia avatar
    301 posts

    Posted 19 Aug Link to this post

    Hello Paulo Rogério,

    The error message indicates that the subreport cannot be found at the specified path. Probably, SGO_Ocorrencias.trdx report was moved from the path specified in the error message to the project's Reports folder. 

    Please open the main report (_SGO_Relatorio_Ocorrencia_Monitoramento.trdx) and correct the URLs in SubReport's ReportSource property.


    Regards,
    Katia
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top