ActiveReports for .NET 18.0J
共有データソースの作成と使用
ActiveReportsユーザーガイド > 概念 > ActiveReports Webデザイナ > 共有データソースの作成と使用

共有データソースには、複数のレポートに同じデータをバインドできる接続プロパティが含まれます。共有データソースは、単体のデザイナまたはVisual Studioに統合されたデザイナでのみ作成および編集できます。Webデザイナでは、既存のデータソースのみを参照できます。

以下は、様々なシナリオでWebデザイナに共有データソースを使用する方法について説明します。

この問題は、共有データソースによって解決されます。レポート定義にはデータソース定義への参照のみが含まれており、レポートのプレビュー時にサーバー側で解決されます。

メモ:共有データソースはデフォルトで無効になっています。

共有データソース(*.rdsx)は、単体のデザイナまたはVisual Studioに統合されたデザイナでのみ作成される必要があります。詳細については、「共有データソースの操作」を参照してください。

以下の手順では、共有データソースを使用する方法について説明します。まず、ASP.NET MVC CoreアプリケーションでWebデザイナを作成する必要があります。詳細については、次のトピックを参照してください。

以下の手順では、WebDesigner_MVC_Coreサンプルに共有データソースを追加する方法について説明します。

  1. WebDesigner_MVC_Coreアプリケーションを開きます。
  2. resourcesフォルダには、共有参照の.rdsxファイルを配置します。
  3. Webデザイナが初期化されるscript.jsファイルに、Sharedプロパティを使用して、共有データソースを有効にします。       
    script.js
    コードのコピー
    import { arWebDesigner } from './web-designer.js';
    import { createViewer } from './jsViewer.min.js';
    let viewer = null;
    let serverUrl = getServerUrl();
    function getServerUrl() {
        let baseUrl = 'api';
        let virtualDirName = document.getElementById('virtualDir');
        if (virtualDirName && virtualDirName.href != window.location.origin + '/') {
            return virtualDirName.href + baseUrl;
        }
        return baseUrl;
    }
    arWebDesigner.create('#ar-web-designer', {
        server: {
            url: serverUrl
        },
        appBar: { openButton: { visible: true } },
        data: { dataSets: { canModify: true }, dataSources: { canModify: true, shared: { enabled: true } } },
        preview: {
            openViewer: (options) => {
                if (viewer) {
                    viewer.theme = options.theme;
                    viewer.openReport(options.documentInfo.id);
                    return;
                }
                viewer = createViewer({
                    element: '#' + options.element,
                    reportService: {
                        url: 'api/reporting',
                    },
                    reportID: options.documentInfo.id,
                    settings: {
                        zoomType: 'FitPage',
                    },
                    theme: options.theme
                });
            }
        }
    });
    

    IReportStoreを実装する

  4. Implementationフォルダを作成します。

  5. Implementationフォルダに、IReportStoreの実装を含むReportStore.csクラスを追加します。

    ReportStore.cs
    コードのコピー
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using GrapeCity.ActiveReports.Rendering.Tools;
    using GrapeCity.ActiveReports.Web.Designer;
    using GrapeCity.ActiveReports.Web.Viewer;
    namespace WebDesigner_MVC_Core.Implementation
    {
        public class ReportStore : IReportStore
        {
            private static readonly string[] ReportExtensions =
            {
            ".rdl",
            ".rdlx",
            ".rdlx-master",
            ".rpx"
        };
            private readonly Dictionary<string, byte[]> _tempStorage = new Dictionary<string, byte[]>();
            private readonly DirectoryInfo _rootDirectory;
            public ReportStore(DirectoryInfo rootDirectory)
            {
                _rootDirectory = rootDirectory;
            }
            public ReportDescriptor GetReportDescriptor(string reportId)
            {
                if (_tempStorage.ContainsKey(reportId))
                    return new ReportDescriptor(GetReportTypeByExtension(Path.GetExtension(reportId)));
                var fileInfo = new FileInfo(Path.Combine(_rootDirectory.FullName, reportId));
                return new ReportDescriptor(GetReportTypeByExtension(fileInfo.Extension));
            }
            public Stream LoadReport(string reportId)
            {
                if (_tempStorage.TryGetValue(reportId, out var tempReport))
                    return new MemoryStream(tempReport);
                var file = new FileInfo(Path.Combine(_rootDirectory.FullName, reportId));           
                return file.OpenRead();
            }
            public string SaveReport(ReportType reportType, string reportId, Stream reportData, SaveSettings settings = SaveSettings.None)
            {
                if ((settings & SaveSettings.IsTemporary) != 0)
                {
                    var tempName = Guid.NewGuid() + GetReportExtension(reportType);
                    _tempStorage.Add(tempName, reportData.ToArray());
                    return tempName;
                }
                var reportFullPath = Path.Combine(_rootDirectory.FullName, reportId);
                using var fileStream = new FileStream(reportFullPath, FileMode.Create, FileAccess.Write);
                reportData.CopyTo(fileStream);
                return reportId;
            }
            public string UpdateReport(ReportType reportType, string reportId, Stream reportData)
            {
                return SaveReport(reportType, reportId, reportData);
            }
            public ReportInfo[] ListReports()
            {
                var reports = _rootDirectory
                    .EnumerateFiles("*.*")
                    .Where(fileInfo => ReportExtensions.Any(ext =>
                        fileInfo.Extension.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase)))
                    .Select(fileInfo => new ReportInfo()
                    {
                        Id = fileInfo.Name,
                        Name = fileInfo.Name,
                        ReportType = GetReportTypeByExtension(fileInfo.Extension),
                    }).ToArray();
                return reports;
            }
            private static ReportType GetReportTypeByExtension(string extension)
            {
                switch (extension)
                {
                    case ".rdl":
                    case ".rdlx":
                        return ReportType.RdlXml;
                    case ".rdlx-master":
                        return ReportType.RdlMasterXml;
                    case ".rpx":
                        return ReportType.RpxXml;
                    default:
                        throw new ArgumentOutOfRangeException(nameof(extension), extension, null);
                }
            }
            private static string GetReportExtension(ReportType type)
            {
                return type switch
                {
                    ReportType.RdlXml => ".rdlx",
                    ReportType.RdlMasterXml => ".rdlx-master",
                    ReportType.RpxXml => ".rpx",
                    _ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
                };
            }
            public void DeleteReport(string reportId)
            {
                if (_tempStorage.ContainsKey(reportId))
                {
                    _tempStorage.Remove(reportId);
                    return;
                }
                var file = new FileInfo(Path.Combine(_rootDirectory.FullName, reportId));
                if (file.Exists)
                    file.Delete(); ;
            }
        }
    }
    

    IResourcesServiceを実装する

  6. IResourcesServiceの実装を追加するには、ImplementationフォルダにResourceService.csを追加します。

    ResourceService.cs
    コードのコピー
    using System.IO;
    using System.Linq;
    using GrapeCity.ActiveReports;
    using GrapeCity.ActiveReports.Rendering.Tools;
    using GrapeCity.ActiveReports.Web.Designer;
    namespace WebDesigner_MVC_Core.Implementation
    {
        public class ResourceProvider : IResourceRepositoryProvider
        {
            private const string SharedDataSourceExtension = ".rdsx";
            private readonly DirectoryInfo _rootDirectory;
            public ResourceProvider(DirectoryInfo rootDirectory)
            {
                _rootDirectory = rootDirectory;
            }
            public Stream GetResource(ResourceInfo resource)
            {
                string absolutePath = Path.Combine(_rootDirectory.FullName, resource.Name);
                var file = new FileInfo(absolutePath);
                if (!file.Exists)
                    return null;
                return file.OpenRead();
            }
            public ResourceDescriptor[] ListResources(ResourceType resourceType)
            {
                if (resourceType == ResourceType.SharedDataSource)
                {
                    var sharedDataSources = _rootDirectory
                        .EnumerateFiles("*" + SharedDataSourceExtension).Select(fileInfo =>
                        {
                            using var stream = fileInfo.OpenRead();
                            var dataSource = DataSourceTools.LoadSharedDataSource(stream);
                            return new SharedDataSourceResourceDescriptor()
                            {
                                Id = fileInfo.Name,
                                Name = fileInfo.Name,
                                Type = dataSource.ConnectionProperties.DataProvider
                            };
                        }).ToArray();
                    return sharedDataSources;
                }
                return Enumerable.Empty<ResourceDescriptor>().ToArray();
            }
            public ResourceDescriptor[] DescribeResources(ResourceInfo[] resources)
            {
                return Enumerable.Empty<ResourceDescriptor>().ToArray();
            }
        }
    }
    

    サービスを構成と登録する

  7. Startup.csを開き、次のようにファイルを更新します。Startup.csファイルは次のような処理を行います。

    1. アプリケーションが使用するサービスとミドルウェアを構成します。
    2. IReportStoreとIResourceRepositoryProviderをシングルトンサービスとして登録します。
    3. レポートおよびデザイナサービスを追加します。
    4. SQLiteデータプロバイダが追加されるActiveReports.configファイルへのパスを設定します。
    5. レポートおよびデザイナのミドルウェアを構成します。
    6. 静的ファイルを提供します。
      Startup.cs
      コードのコピー
      using System.IO;
      using Microsoft.AspNetCore.Builder;
      using Microsoft.AspNetCore.Hosting;
      using Microsoft.Extensions.Hosting;
      using Microsoft.Extensions.Configuration;
      using Microsoft.Extensions.DependencyInjection;
      using GrapeCity.ActiveReports.Aspnetcore.Viewer;
      using GrapeCity.ActiveReports.Aspnetcore.Designer;
      using System.Text;
      using GrapeCity.ActiveReports.Web.Designer;
      using WebDesigner_MVC_Core.Implementation;
      using System;
      namespace WebDesignerMvcCore
      {
          public class Startup
          {
              private static readonly DirectoryInfo ResourcesRootDirectory =
                  new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "resources" + Path.DirectorySeparatorChar));
              public Startup(IConfiguration configuration)
              {
                  Configuration = configuration;
              }
              public IConfiguration Configuration { get; }
              // このメソッドはランタイムによって呼び出されます。このメソッドを使用して、コンテナにサービスを追加します。
              public void ConfigureServices(IServiceCollection services)
              {
                  Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                  services
                      .AddReportViewer()
                      .AddReportDesigner()
                      .AddSingleton<IReportStore>(new ReportStore(ResourcesRootDirectory))
                      .AddSingleton<IResourceRepositoryProvider>(new ResourceProvider(ResourcesRootDirectory))
                      .AddMvc(options => options.EnableEndpointRouting = false)
                      .AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
              }
              // このメソッドはランタイムによって呼び出されます。このメソッドを使用して、HTTP要求パイプラインを構成します。
                                     
                  public void Configure(IApplicationBuilder app,
                  IWebHostEnvironment env,
                  IReportStore reportStore,
                  IResourceRepositoryProvider resourceProvider
                  )
              {
                  if (env.IsDevelopment())
                  {
                      app.UseDeveloperExceptionPage();
                  }
                  var pathToConfig = Path.Combine(Environment.CurrentDirectory, "ActiveReports.config");
                  app.UseReportDesigner(config =>
                  {
                      config.UseReportsProvider(reportStore);
                      config.UseResourcesProvider(resourceProvider);
                      config.UseConfig(pathToConfig);
                  });
                  app.UseFileServer();
                  app.UseMvc();
              }
          }
      }
      
  8. 以下の内容でActiveReports.configファイルを追加します。

    ActiveReports.config
    コードのコピー
    <?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. アプリケーションを実行します。
  10. データ]タブに移動し、データソースを追加します。

  11. [データソースエディタ]ダイアログでは、種類で[共有参照]を選択し、参照で「.rdsx」ファイルを選択します。Shared Reference configuration in Data Source Editor dialog