|
2 | 2 | { |
3 | 3 | using Microsoft.EntityFrameworkCore; |
4 | 4 | using SqlDefinitionStorageExample.EFCore; |
5 | | - using System; |
6 | 5 | using System.IO; |
7 | 6 | using System.Linq; |
8 | | - using Telerik.Reporting.Processing; |
9 | 7 | using Telerik.WebReportDesigner.Services; |
10 | 8 | using Data = Telerik.Reporting.Processing.Data; |
11 | 9 |
|
12 | | - /// <summary> |
13 | | - /// An example of a custom implementation of <see cref="Data.ISharedDataSourceResolver"/>. |
14 | | - /// The relative sharedDataSourcePath is resolved to absolute path using the <see cref="Configuration.Instance"/> paths. |
15 | | - /// If at any of the locations the requested .sdsx file, is found, the <see cref="CustomSharedDataSourceResolver"/> deserializes the file contents of the provided path and instantiates a DataSource class. |
16 | | - /// The CustomSharedDataSourceResolver needs to be registered in application's configuration file appsettings.json. |
17 | | - /// </summary> |
18 | 10 | class CustomSharedDataSourceResolver : Data.ISharedDataSourceResolver |
19 | 11 | { |
20 | | - /// <summary> |
21 | | - /// Resolves and returns a DataSource instance from the provided <paramref name="sharedDataSourcePath"/> parameter. |
22 | | - /// </summary> |
23 | | - /// <param name="sharedDataSourcePath">The value of the Path property obtained from the report definition. Might be relative or absolute.</param> |
24 | | - /// <returns></returns> |
25 | | - Telerik.Reporting.DataSource Data.ISharedDataSourceResolver.Resolve(string sharedDataSourcePath) |
26 | | - { |
27 | | - var context = (SqlDefinitionStorageContext)Configuration.Instance.DbContext; |
28 | | - |
29 | | - if (context == null) { |
30 | | - throw new NullReferenceException($"The path {sharedDataSourcePath} cannot be resolved."); |
31 | | - } |
32 | | - |
33 | | - var sds = context.Resources.FirstOrDefault(m => m.Uri == sharedDataSourcePath); |
34 | | - using (var ms = new MemoryStream(sds.Bytes)) |
35 | | - { |
36 | | - return (Telerik.Reporting.DataSource)new Telerik.Reporting.XmlSerialization.ReportXmlSerializer() |
37 | | - .Deserialize(ms); |
38 | | - } |
39 | | - |
40 | | - //ValidateConfiguration(); |
41 | | - |
42 | | - //var absolutePathToSharedDataSourceDefinition = |
43 | | - // GetExistingFilePath(Configuration.Instance.ReportsPath, sharedDataSourcePath) |
44 | | - // ?? GetExistingFilePath(Configuration.Instance.SharedDataSourcesPath, sharedDataSourcePath); |
45 | | - |
46 | | - //if (string.IsNullOrEmpty(absolutePathToSharedDataSourceDefinition)) |
47 | | - //{ |
48 | | - // throw new NullReferenceException($"The path {sharedDataSourcePath} cannot be resolved."); |
49 | | - //} |
50 | | - |
51 | | - //using (var fs = new FileStream(absolutePathToSharedDataSourceDefinition, FileMode.Open, FileAccess.Read, FileShare.Read)) |
52 | | - //{ |
53 | | - // return (Telerik.Reporting.DataSource)new Telerik.Reporting.XmlSerialization.ReportXmlSerializer() |
54 | | - // .Deserialize(fs); |
55 | | - //} |
56 | | - } |
57 | 12 |
|
58 | | - static string GetExistingFilePath(string basePath, string sharedDataSourcePath) |
| 13 | + readonly string _root = "Shared Data Sources"; |
| 14 | + Telerik.Reporting.DataSource Data.ISharedDataSourceResolver.Resolve(string sharedDataSourcePath) |
59 | 15 | { |
60 | | - var sharedDataSourceAbsolutePath = new PathResourceResolver(basePath) |
61 | | - .Resolve(sharedDataSourcePath) as string; |
62 | | - |
63 | | - if (!string.IsNullOrEmpty(sharedDataSourceAbsolutePath) && File.Exists(sharedDataSourceAbsolutePath)) |
64 | | - { |
65 | | - return sharedDataSourceAbsolutePath; |
66 | | - } |
67 | | - |
68 | | - return null; |
69 | | - } |
70 | 16 |
|
71 | | - static void ValidateConfiguration() |
72 | | - { |
73 | | - if (string.IsNullOrEmpty(Configuration.Instance.ReportsPath) || string.IsNullOrEmpty(Configuration.Instance.SharedDataSourcesPath)) |
| 17 | + if (!sharedDataSourcePath.Contains($"{_root}\\")) |
74 | 18 | { |
75 | | - throw new NullReferenceException("The configuration of the CustomSharedDataSourceResolver is not initialized. Please make sure you've called \"Configuration.Instance.Init(string reportsPath, string sharedDataSourcesPath)\" method and have provided valid paths as arguments."); |
| 19 | + sharedDataSourcePath = $"{_root}\\{sharedDataSourcePath}"; |
76 | 20 | } |
77 | | - } |
78 | | - |
79 | | - /// <summary> |
80 | | - /// Class that stores the paths to Reports and Shared Data Sources folders. |
81 | | - /// </summary> |
82 | | - internal class Configuration |
83 | | - { |
84 | | - public static Configuration Instance = new(); |
85 | 21 |
|
86 | | - public string ReportsPath { get; private set; } |
| 22 | + sharedDataSourcePath = sharedDataSourcePath.Replace("/", "\\"); |
87 | 23 |
|
88 | | - public string SharedDataSourcesPath { get; private set; } |
| 24 | + var optionsBuilder = new DbContextOptionsBuilder<SqlDefinitionStorageContext>(); |
| 25 | + // It is necessary to initialize a new dbContent because this code will be executed in a new thread |
| 26 | + using SqlDefinitionStorageContext dbContext = new(optionsBuilder.Options); |
89 | 27 |
|
90 | | - public DbContext DbContext { get; private set; } |
| 28 | + var sds = dbContext.Resources.FirstOrDefault(m => m.Uri == sharedDataSourcePath) ?? throw new ResourceNotFoundException(); |
| 29 | + using var ms = new MemoryStream(sds.Bytes); |
91 | 30 |
|
92 | | - public void Init(string reportsPath, string sharedDataSourcesPath, DbContext dbContext) |
93 | | - { |
94 | | - this.ReportsPath = reportsPath; |
95 | | - this.SharedDataSourcesPath = sharedDataSourcesPath; |
96 | | - this.DbContext = dbContext; |
97 | | - } |
| 31 | + return (Telerik.Reporting.DataSource)new Telerik.Reporting.XmlSerialization.ReportXmlSerializer() |
| 32 | + .Deserialize(ms); |
98 | 33 | } |
99 | 34 | } |
100 | 35 | } |
0 commit comments