[]
共有データソースには、複数のレポートを同じデータにバインドできる接続プロパティが含まれます。共有データソースは、単体のデザイナまたはVisual Studioに統合されたデザイナでのみ作成および編集できます。Webデザイナでは既存のデータソースのみを参照できます。
以下は、様々なシナリオでWebデザイナに共有データソースを使用する方法について説明します。
接続文字列の情報をユーザーに表示されないようにする
ユーザーが事前定義されたデータソースとデータセットを選択できるようにする
この問題は、共有データソースによって解決されます。レポート定義にはデータソース定義への参照のみが含まれており、レポートのプレビュー時にサーバー側で解決されます。
メモ:共有データソースはデフォルトでは無効になっています。
共有データソース(*.rdsx)は、単体のデザイナまたはVisual Studioに統合されたデザイナでのみ作成される必要があります。詳細については、「共有データソースの操作」を参照してください。
以下の手順では、BlazorDesignerServerサンプルに共有データソースを追加する方法について説明します。
BlazorDesignerServerアプリケーションを開きます。
resourcesフォルダには、共有参照の.rdsxファイルを配置します。
Webデザイナが初期化されるIndex.razorページに、Sharedプロパティを使用して、共有データソースを有効にします。
@page "/"
@inject IJSRuntime JSRuntime
<PageTitle>Index</PageTitle>
<link href="_content/@(typeof(ReportViewer).Assembly.GetName().Name)/jsViewer.min.css" rel="stylesheet" />
<div id="designerContainer">
<ReportDesigner @ref="_designer" RpxSettings="@_rpx" AppBarSettings="@_appBar" DataSettings="@_data" PreviewSettings="@_preview" />
</div>
@code {
private ReportDesigner _designer;
private ReportViewer _viewer;
private RpxSettings _rpx;
private AppBarSettings _appBar;
private DataSettings _data;
private PreviewSettings _preview;
public Index()
{
_rpx = new RpxSettings
{
Enabled = true
};
_appBar = new AppBarSettings
{
OpenButton = new OpenButton { Visible = true }
};
_data = new DataSettings
{
DataSets = new DataSets { CanModify = true },
DataSources = new DataSources
{
CanModify = true,
Shared = new SharedDataSourceOptions()
{
Enabled = true
}
}
};
_preview = new PreviewSettings
{
OpenViewer = OpenViewer
};
}
private async void OpenViewer(ViewerSettings settings)
{
if(_viewer != null)
{
await _viewer.SetTheme(settings.Theme);
await _viewer.OpenReport(settings.DocumentInfo.Id);
return;
}
_viewer = new ReportViewer();
var initOptions = new InitializationOptions();
initOptions.ReportID = settings.DocumentInfo.Id;
initOptions.PanelsLocation = PanelsLocation.toolbar;
initOptions.Theme = settings.Theme;
initOptions.ReportLoaded = (reportInfo) =>
{
};
await _viewer.Render(JSRuntime, settings.Element, initOptions);
}
}IReportStoreを実装する
Implementationフォルダを作成します。
Implementationフォルダに、IReportStoreの実装を含むReportStore.csクラスを追加します。
using GrapeCity.ActiveReports.Rendering.Tools;
using GrapeCity.ActiveReports.Web.Designer;
using GrapeCity.ActiveReports.Web.Viewer;
namespace BlazorDesignerServer.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));
//if (!file.Exists)
// throw new ReportNotFoundException();
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(); ;
}
}
}Implement the IResourceRepositoryProvider
IResourceRepositoryProviderの実装を追加するには、ImplementationフォルダにResourceProvider.csを追加します。
using GrapeCity.ActiveReports.Rendering.Tools;
using GrapeCity.ActiveReports.Web.Designer;
using GrapeCity.ActiveReports;
namespace BlazorDesignerServer.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();
}
}
}サービスを構成と登録する
Program.csを開き、次のようにファイルを更新します。Program.csファイルは次のような処理を行います。
アプリケーションが使用するサービスとミドルウェアを構成します。
IReportStoreとIResourceRepositoryProviderをシングルトンサービスとして登録します。
レポートおよびデザイナサービスを追加します。
SQLiteデータプロバイダが追加されるActiveReports.configファイルへのパスを設定します。
レポートおよびデザイナのミドルウェアを構成します。
静的ファイルを提供します。
Program.csの完全なコードは次のようになります。
using GrapeCity.ActiveReports.Aspnetcore.Designer;
using GrapeCity.ActiveReports.Aspnetcore.Viewer;
using Microsoft.AspNetCore.SignalR;
using System.Text;
using GrapeCity.ActiveReports.Web.Designer;
using BlazorDesignerServer.Implementation;
var builder = WebApplication.CreateBuilder(args);
var ResourcesRootDirectory =
new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "resources"));
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
// コンテナにサービスを追加します。
builder.Services.AddReportViewer();
builder.Services.AddReportDesigner();
builder.Services.AddSingleton<IReportStore>(new ReportStore(ResourcesRootDirectory));
builder.Services.AddSingleton<IResourceRepositoryProvider>(new ResourceProvider(ResourcesRootDirectory));
builder.Services.AddRazorPages().AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
builder.Services.AddServerSideBlazor();
builder.Services.Configure<HubOptions>(options =>
{
options.MaximumReceiveMessageSize = 524288000; //500MB
});
builder.Services.AddCors();
var app = builder.Build();
// HTTP要求パイプラインを構成します。
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
// BlazorWebAssemblyのサーバーとして使用するために次の設定を行います。
app.UseCors(cors => cors.SetIsOriginAllowed(origin => new Uri(origin).Host == "localhost")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithExposedHeaders("Content-Disposition"));
var reportStore = app.Services.GetService<IReportStore>();
var resourceProvider = app.Services.GetService<IResourceRepositoryProvider>();
app.UseReportDesigner(config =>
{
config.UseReportsProvider(reportStore);
config.UseResourcesProvider(resourceProvider);
});
app.UseStaticFiles();
app.UseRouting();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();アプリケーションを実行します。
[データ]タブに移動し、データソースを追加します。
[データソースエディタ]ダイアログでは、種類で[共有参照]を選択し、参照で「.rdsx」ファイルを選択します。
