-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCustomReportStorageWebExtension.cs
128 lines (114 loc) · 5.69 KB
/
CustomReportStorageWebExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using DevExpress.XtraReports.UI;
using DevExpress.XtraReports.Web.ClientControls;
using Microsoft.AspNetCore.Hosting;
using ReportingAppAsyncServices.PredefinedReports;
namespace ReportingAppAsyncServices.Services
{
public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extensions.ReportStorageWebExtension
{
readonly string ReportDirectory;
const string FileExtension = ".repx";
public CustomReportStorageWebExtension(IWebHostEnvironment env)
{
ReportDirectory = Path.Combine(env.ContentRootPath, "Reports");
if (!Directory.Exists(ReportDirectory))
{
Directory.CreateDirectory(ReportDirectory);
}
}
private bool IsWithinReportsFolder(string url, string folder)
{
var rootDirectory = new DirectoryInfo(folder);
var fileInfo = new FileInfo(Path.Combine(folder, url));
return fileInfo.Directory.FullName.ToLower().StartsWith(rootDirectory.FullName.ToLower());
}
public override async Task<byte[]> GetDataAsync(string url)
{
// Returns report layout data stored in a Report Storage using the specified URL.
// This method is called only for valid URLs after the IsValidUrl method is called.
try
{
if (Directory.EnumerateFiles(ReportDirectory).Select(Path.GetFileNameWithoutExtension).Contains(url))
{
return await File.ReadAllBytesAsync(Path.Combine(ReportDirectory, url + FileExtension));
}
if (ReportsFactory.Reports.ContainsKey(url))
{
using (MemoryStream ms = new MemoryStream())
{
ReportsFactory.Reports[url]().SaveLayoutToXml(ms);
return ms.ToArray();
}
}
}
catch (Exception ex)
{
throw new DevExpress.XtraReports.Web.ClientControls.FaultException("Could not get report data.", ex);
}
throw new DevExpress.XtraReports.Web.ClientControls.FaultException(string.Format("Could not find report '{0}'.", url));
}
public override Task<Dictionary<string, string>> GetUrlsAsync()
{
// Returns a dictionary of the existing report URLs and display names.
// This method is called when running the Report Designer,
// before the Open Report and Save Report dialogs are shown and after a new report is saved to a storage.
return Task.FromResult(Directory.GetFiles(ReportDirectory, "*" + FileExtension)
.Select(Path.GetFileNameWithoutExtension)
.Union(ReportsFactory.Reports.Select(x => x.Key))
.ToDictionary<string, string>(x => x));
}
public override Task SetDataAsync(XtraReport report, string url)
{
// Stores the specified report to a Report Storage using the specified URL.
// This method is called only after the IsValidUrl and CanSetData methods are called.
if (!IsWithinReportsFolder(url, ReportDirectory))
throw new DevExpress.XtraReports.Web.ClientControls.FaultException("Invalid report name.");
report.SaveLayoutToXml(Path.Combine(ReportDirectory, url + FileExtension));
return Task.CompletedTask;
}
public override async Task<string> SetNewDataAsync(XtraReport report, string defaultUrl)
{
// Stores the specified report using a new URL.
// The IsValidUrl and CanSetData methods are never called before this method.
// You can validate and correct the specified URL directly in the SetNewData method implementation
// and return the resulting URL used to save a report in your storage.
await SetDataAsync(report, defaultUrl);
return defaultUrl;
}
public override bool CanSetData(string url)
{
// Determines whether or not it is possible to store a report by a given URL.
// For instance, make the CanSetData method return false for reports that should be read-only in your storage.
// This method is called only for valid URLs (i.e., if the IsValidUrl method returned true) before the SetData method is called.
return true;
}
public override bool IsValidUrl(string url)
{
// Determines whether or not the URL passed to the current Report Storage is valid.
// For instance, implement your own logic to prohibit URLs that contain white spaces or some other special characters.
// This method is called before the CanSetData and GetData methods.
return Path.GetFileName(url) == url;
}
public override void SetData(XtraReport report, string url)
{
throw new FaultException("SetData was called");
}
public override string SetNewData(XtraReport report, string defaultUrl)
{
throw new FaultException("SetNewData was called");
}
public override byte[] GetData(string url)
{
throw new FaultException("GetData was called");
}
public override Dictionary<string, string> GetUrls()
{
throw new FaultException("GetUrls was called");
}
}
}