The shared data sources contain connection properties that allow binding multiple reports to the 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 in Blazor application. See Blazor Server Application topic for more information.
Index.razor |
Copy Code
|
---|---|
@page "/" @inject IJSRuntime JSRuntime <PageTitle>Index</PageTitle> <link href="_content/GrapeCity.ActiveReports.Blazor.Viewer/jsViewer.min.css" rel="stylesheet" /> <div id="designerContainer"> <ReportDesigner @ref="_designer" PreviewSettings=@_preview DataSettings="@_data" /> </div> @code { private ReportDesigner _designer; private DataSettings _data; private PreviewSettings _preview; public Index() { _data = new DataSettings { DataSets = new DataSets { CanModify = true }, DataSources = new DataSources { CanModify = true, Shared = new SharedDataSourceOptions() { Enabled = true } }, }; _preview = new PreviewSettings { CanPreview = false }; } } |
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 { private DirectoryInfo _resourcesRootDirectory = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "resources")); public SharedDataSourceInfo[] GetSharedDataSourceList() { return _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(_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 Dictionary<string, SectionReport> _tempSectionStorage = new Dictionary<string, SectionReport>(); private readonly ResourceLocator _resourceLocator; private DirectoryInfo _resourcesRootDirectory = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "resources"+ Path.DirectorySeparatorChar)); public ResourceService() { _resourceLocator = new DefaultResourceLocator(new Uri(_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(_resourcesRootDirectory.FullName, id); var reportXml = File.ReadAllBytes(reportFullPath); var report = ReportConverter.FromXML(reportXml); report.Site = new ReportSite(_resourceLocator); return report; } public IReportInfo[] GetReportsList() { return _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(_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(_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 Program.cs and update the file as shown below. The Startup.cs file does the following:
Program.cs |
Copy Code
|
---|---|
using BlazorDesignerServer.Implementation; using BlazorDesignerServer.Services; using GrapeCity.ActiveReports.Aspnetcore.Designer; using GrapeCity.ActiveReports.Aspnetcore.Viewer; using Microsoft.AspNetCore.SignalR; using System.Text; using GrapeCity.ActiveReports.Aspnetcore.Designer.Services; using IDataSetsService = BlazorDesignerServer.Services.IDataSetsService; var builder = WebApplication.CreateBuilder(args); var ResourcesRootDirectory = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "resources")); var TemplatesRootDirectory = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "templates")); var DataSetsRootDirectory = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "datasets")); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // Add services to the container. builder.Services.AddReporting(); builder.Services.AddDesigner(); builder.Services.AddRazorPages().AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null); builder.Services.AddServerSideBlazor(); builder.Services.Configure<HubOptions>(options => { options.MaximumReceiveMessageSize = 524288000; //500MB }); builder.Services.AddSingleton<IResourcesService, ResourceService>(); builder.Services.AddSingleton<ISharedDataSourceService, SharedDataSourceService>(); builder.Services.AddSingleton<ITemplatesService>(new FileSystemTemplates(TemplatesRootDirectory)); builder.Services.AddSingleton<IDataSetsService>(new FileSystemDataSets(DataSetsRootDirectory)); builder.Services.AddCors(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); } // For use as a server for BlazorWebAssembly app.UseCors(cors => cors.SetIsOriginAllowed(origin => new Uri(origin).Host == "localhost") .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials() .WithExposedHeaders("Content-Disposition")); app.UseReporting(config => { config.UseCustomStore(id => { var resourcesService = app.Services.GetRequiredService<IResourcesService>(); return resourcesService.GetReport(id); }); }); app.UseDesigner(config => { var sharedDataSourceService = app.Services.GetRequiredService<ISharedDataSourceService>(); var resourcesService = app.Services.GetRequiredService<IResourcesService>(); config.UseCustomStore(resourcesService); config.UseSharedDataSources(sharedDataSourceService); }); app.UseStaticFiles(); app.UseRouting(); app.MapControllers(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); app.Run(); |
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.