ActiveReports 17 .NET Edition
Developers / Create Applications / WebDesigner Application / Configure and Use Shared Data Sources
In This Topic
    Configure and Use Shared Data Sources
    In This Topic

    The shared data sources contain connection properties that allow binding multiple reports to same data. The shared data sources can be created and edited only in Standalone Designer or VS Integrated Designer. In WebDesigner, however, you can only reference an existing data source.

    Following are the scenarios for using shared data sources in web designer:

    The shared data source solves this problem because the report definition contains only the reference to the data source definition, which is resolved on the server-side when a report is previewed.

    Note: Shared data sources are disabled by default.

    You must create a shared data source (.rdsx) in Standalone Designer or Visual Studio Integrated Designer. See Work with Local Shared Data Sources for more information.

    The steps to use shared data sources are elaborated below. You should first create a WebDesigner-integrated ASP.NET MVC Core application. See the following pages for the information on:

    1. Open the WebDesigner application.
    2. Place the shared reference, a .rdsx file, in the ‘resources’ folder of the project.
    3. In the Index.html where web designer is initialized, use shared property as shown in the following code to enable shared data sources.
      Index.html
      Copy Code
      <!DOCTYPE html>
      <html>
      <head>
          <!-- get these files from the installation location for the package: \node_modules\@grapecity\ar-designer\dist -->
          <link rel="stylesheet" href="web-designer.css" />
          <script src="web-designer.js"></script>
      </head>
      <body>
          <div id="ar-web-designer" class="ar-web-designer">
          </div>
          <script>
              GrapeCity.ActiveReports.Designer.create('#ar-web-designer', {         
                  data: {
                      dataSets: {
                         canModify: true
                      },
                      dataSources: {
                          canModify: true,
                          shared: { enabled: true }
                      }
                  }         
               });
          </script>
      </body>
      </html>
      

      Implement the ISharedDataSourceService

    4. Create 'Implementation' folder.

    5. To the 'Implementation' folder, add ‘SharedDataSourceService.cs’ class which will contain implementation for ISharedDataSourceService.

      SharedDataSourceService.cs
      Copy Code
      public class SharedDataSourceService : ISharedDataSourceService
      {
          public SharedDataSourceInfo[] GetSharedDataSourceList()
          {
              return Startup.ResourcesRootDirectory
                  .EnumerateFiles("*.rdsx")
                  .Select(x =>
                  {
                      var dataSource = GetDataSource(x.Name);
                      return new SharedDataSourceInfo()
                      {
                          Name = x.Name,
                          Type = dataSource.ConnectionProperties.DataProvider
                      };
                  }).ToArray();
          }
          public DataSource GetDataSource(string name)
          {
              return DataSourceTools.LoadSharedDataSource(Path.Combine(Startup.ResourcesRootDirectory.FullName, name));
          }
      }
      

      Implement the IResourcesService

    6. Add 'ResourceService.cs'  to the 'Implementation' folder to add implementation for IResourcesService.

      ResourceService.cs
      Copy Code
      public class ResourceService: IResourcesService
      {
          private readonly Dictionary<string, Report> _tempStorage = new Dictionary<string, Report>();
          private readonly ResourceLocator _resourceLocator;
         
          public ResourceService()
          {
              _resourceLocator = new DefaultResourceLocator(new Uri(Startup.ResourcesRootDirectory.FullName));
          }
         
          public Report GetReport(string id)
          {
              if (_tempStorage.TryGetValue(id, out var tempReport))
              {
                  tempReport.Site = new ReportSite(_resourceLocator);
                  return tempReport;
              }
             
              var reportFullPath = Path.Combine(Startup.ResourcesRootDirectory.FullName, id);
              var reportXml = File.ReadAllBytes(reportFullPath);
              var report = ReportConverter.FromXML(reportXml);
              report.Site = new ReportSite(_resourceLocator);
                 
              return report;
          }
          public IReportInfo[] GetReportsList()
          {
              return Startup.ResourcesRootDirectory
                  .EnumerateFiles("*.rdlx")
                  .Select(x =>
                  {
                      var reportXml = File.ReadAllBytes(x.FullName);
                      var report = ReportConverter.FromXML(reportXml);
                      return new ReportInfo
                      {
                          Id = x.Name,
                          Name = x.Name,
                          Type = report.IsFixedPageReport ? "FPL" : "CPL"
                      };
                  }).Cast<IReportInfo>().ToArray();
          }
          public string SaveReport(string name, Report report, bool isTemporary = false)
          {
              if (isTemporary)
              {
                  var tempName = Guid.NewGuid() + ".rdlx";
                  _tempStorage.Add(tempName, report);
                  return tempName;
              }
             
              var reportFullPath = Path.Combine(Startup.ResourcesRootDirectory.FullName, name);
              report.Name = name;
              var reportXml = ReportConverter.ToXml(report);
              File.WriteAllBytes(reportFullPath, reportXml);
              return name;
          }
          public string UpdateReport(string id, Report report)
          {
              return SaveReport(id, report, false);
          }
          public void DeleteReport(string id)
          {
              if (_tempStorage.ContainsKey(id))
              {
                  _tempStorage.Remove(id);
                  return;
              }
             
              var reportFullPath = Path.Combine(Startup.ResourcesRootDirectory.FullName, id);
             
              if(File.Exists(reportFullPath))
                  File.Delete(reportFullPath);
          }
          public Uri GetBaseUri()
          {
              return _resourceLocator.BaseUri;
          }
          public Theme GetTheme(string id)
          {
              throw new NotImplementedException();
          }
          public IThemeInfo[] GetThemesList()
          {
              return Array.Empty<IThemeInfo>();
          }
          public byte[] GetImage(string id, out string mimeType)
          {
              throw new NotImplementedException();
          }
          public IImageInfo[] GetImagesList()
          {
              return Array.Empty<IImageInfo>();
          }
      }
      public class ReportInfo : IReportInfo
      {
          public string Id { get; set; }
          public string Name { get; set; }
          public string Type { get; set; }
      }
      class ReportSite : ISite
      {
          private readonly ResourceLocator _resourceLocator;
          public ReportSite(ResourceLocator resourceLocator) =>
              _resourceLocator = resourceLocator;
          public object GetService(Type serviceType) =>
              serviceType == typeof(ResourceLocator) ? _resourceLocator : null;
          public IComponent Component => null;
          public IContainer Container => null;
          public bool DesignMode => false;
          public string Name { get; set; }
      }
      

      Configure and register services

    7. Open Startup.cs and update the file as shown below. The Startup.cs file does the following:

      1. configures the services and middleware used by the application
      2. registers the 'ISharedDataSourceService' and 'IResourcesService' as singleton services
      3. adds reporting and designer services
      4. sets the path to the GrapeCity.ActiveReports.config file where the SQLite provider is added
      5. configures the reporting and designer middleware
      6. serves static files
                       
        Startup.cs
        Copy Code
        public class Startup
        {
            public static readonly DirectoryInfo ResourcesRootDirectory =
                new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "resources" + Path.DirectorySeparatorChar));
               
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
            public IConfiguration Configuration { get; }
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                services
                    .AddSingleton<ISharedDataSourceService, SharedDataSourceService>()
                    .AddSingleton<IResourcesService, ResourceService>()
                    .AddReporting()
                    .AddDesigner();
            }
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app,
                IWebHostEnvironment env,
                IResourcesService resourcesService,
                ISharedDataSourceService sharedDataSourceService)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                   
                var pathToConfig = Path.Combine(Environment.CurrentDirectory, "GrapeCity.ActiveReports.config");
                app.UseReporting(config =>
                {
                    config.UseCustomStore(resourcesService.GetReport);
                    config.UseConfig(pathToConfig);
                });
                app.UseDesigner(config =>
                {
                    config.UseCustomStore(resourcesService);
                    config.UseSharedDataSources(sharedDataSourceService);
                    config.UseConfig(pathToConfig);
                });
                app.UseDefaultFiles();
                app.UseStaticFiles();
            }
        }
        
    8. Add 'GrapeCity.ActiveReports.config' with following content.

      GrapeCity.ActiveReports.config
      Copy Code
      <?xml version="1.0" encoding="utf-8" ?>
      <Configuration>
          <Extensions>
              <Data>
                  <Extension Name="SQLITE" Type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite"
                             DisplayName="Sqlite Provider" />
              </Data>
          </Extensions>
      </Configuration>
      
    9. Run the application.
    10. Go to the Data tab to add the data source.

    11. In the Data Source Editor dialog, select ‘Shared Reference’ as Provider and then the ‘.rdsx’ file as Reference.Shared Reference configuration in Data Source Editor dialog

    See Also