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.
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:
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> |
Create 'Implementation' folder.
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)); } } |
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; } } |
Open Startup.cs and update the file as shown below. The Startup.cs file does the following:
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(); } } |
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> |
Go to the Data tab to add the data source.
In the Data Source Editor dialog, select ‘Shared Reference’ as Provider and then the ‘.rdsx’ file as Reference.