Skip to content

Commit 1c6d997

Browse files
committed
implement shared data source overwrite rename download and sdsx resolver
1 parent 3cf7d1c commit 1c6d997

14 files changed

+128
-330
lines changed

SqlDefinitionStorageExample/CustomDefinitionStorage.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ public CustomDefinitionStorage(SqlDefinitionStorageContext dbContext, string roo
4444

4545
public new Task<IEnumerable<ResourceModelBase>> GetFolderContentsAsync(string uri)
4646
{
47-
//var newUri = string.IsNullOrEmpty(uri)
48-
// ? Root
49-
// : Root + "\\" + (uri ?? "");
50-
5147
return base.GetFolderContentsAsync(PrepareResourceUri(uri));
5248
}
5349

SqlDefinitionStorageExample/CustomReportSourceResolver.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,7 @@ public ReportSource Resolve(string uri, OperationOrigin operationOrigin, IDictio
2525
uri = $"Reports\\{uri}";
2626
}
2727

28-
var report = _dbContext.Resources.FirstOrDefault(r => r.Uri == uri.Replace("/", "\\"));
29-
30-
if (report == null)
31-
{
32-
throw new FileNotFoundException();
33-
}
34-
28+
var report = _dbContext.Resources.FirstOrDefault(r => r.Uri == uri.Replace("/", "\\")) ?? throw new FileNotFoundException();
3529
MemoryStream stream = new(report.Bytes);
3630
Telerik.Reporting.Report reportDocument = (Telerik.Reporting.Report)reportPackager.UnpackageDocument(stream);
3731

SqlDefinitionStorageExample/CustomResourceResolver.cs

Lines changed: 0 additions & 117 deletions
This file was deleted.

SqlDefinitionStorageExample/CustomResourceStorage.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,15 @@ public IEnumerable<ResourceFileModel> GetAllByExtension(string[] extensions)
9494

9595
public byte[] GetByUri(string uri)
9696
{
97-
return DbContext.Resources.FirstOrDefault(r => r.Uri == uri).Bytes;
97+
uri = uri.Replace("/", "\\");
98+
var resource = DbContext.Resources.FirstOrDefault(r => r.Uri == uri);
99+
100+
if (resource == null)
101+
{
102+
throw new ResourceNotFoundException($"The resource located at {uri} cannot be found.");
103+
}
104+
105+
return resource.Bytes;
98106
}
99107

100108
public ResourceFileModel GetModelByName(string resourceName)

SqlDefinitionStorageExample/CustomSharedDataSourceResolver.cs

Lines changed: 12 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2,99 +2,34 @@
22
{
33
using Microsoft.EntityFrameworkCore;
44
using SqlDefinitionStorageExample.EFCore;
5-
using System;
65
using System.IO;
76
using System.Linq;
8-
using Telerik.Reporting.Processing;
97
using Telerik.WebReportDesigner.Services;
108
using Data = Telerik.Reporting.Processing.Data;
119

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>
1810
class CustomSharedDataSourceResolver : Data.ISharedDataSourceResolver
1911
{
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-
}
5712

58-
static string GetExistingFilePath(string basePath, string sharedDataSourcePath)
13+
readonly string _root = "Shared Data Sources";
14+
Telerik.Reporting.DataSource Data.ISharedDataSourceResolver.Resolve(string sharedDataSourcePath)
5915
{
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-
}
7016

71-
static void ValidateConfiguration()
72-
{
73-
if (string.IsNullOrEmpty(Configuration.Instance.ReportsPath) || string.IsNullOrEmpty(Configuration.Instance.SharedDataSourcesPath))
17+
if (!sharedDataSourcePath.Contains($"{_root}\\"))
7418
{
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}";
7620
}
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();
8521

86-
public string ReportsPath { get; private set; }
22+
sharedDataSourcePath = sharedDataSourcePath.Replace("/", "\\");
8723

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);
8927

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);
9130

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);
9833
}
9934
}
10035
}

SqlDefinitionStorageExample/CustomSharedDataSourceStorage.cs

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using DocumentFormat.OpenXml.Drawing.Charts;
2-
using Microsoft.EntityFrameworkCore;
3-
using SqlDefinitionStorageExample.EFCore;
1+
using SqlDefinitionStorageExample.EFCore;
42
using SqlDefinitionStorageExample.EFCore.Models;
53
using System;
64
using System.Collections.Generic;
@@ -20,28 +18,58 @@ Task<SharedDataSourceModel> ISharedDataSourceStorage.GetModelAsync(string uri)
2018

2119
Task<SharedDataSourceModel> ISharedDataSourceStorage.SaveAsync(SaveResourceModel model, byte[] resource)
2220
{
23-
return Task.FromResult(SaveCore(model, resource) as SharedDataSourceModel);
21+
return Task.FromResult(SaveCore(model, resource));
2422
}
2523

2624
Task<SharedDataSourceModel> ISharedDataSourceStorage.RenameAsync(RenameResourceModel model)
2725
{
28-
throw new NotImplementedException();
26+
return Task.FromResult(RenameCore(model));
2927
}
3028

3129
public new Task<ResourceFileModel> SaveAsync(SaveResourceModel model, byte[] resource)
3230
{
33-
return Task.FromResult(SaveCore(model, resource));
31+
return Task.FromResult(SaveCore(model, resource) as ResourceFileModel);
32+
}
33+
34+
Task<ResourceFileModel> IAssetsStorage.RenameAsync(RenameResourceModel model)
35+
{
36+
return Task.FromResult(RenameCore(model) as ResourceFileModel);
3437
}
3538

3639
public new ResourceFileModel Overwrite(OverwriteResourceModel model, byte[] resource)
3740
{
38-
throw new System.NotImplementedException();
41+
var entity = DbContext.Resources.FirstOrDefault(r => r.Uri == $"Shared Data Sources\\{model.Uri}") ?? throw new ResourceNotFoundException();
42+
entity.Bytes = resource;
43+
entity.ModifiedOn = DateTime.Now;
44+
entity.Description = SharedDataSourceDescriptionHelper.Read(resource);
45+
46+
DbContext.SaveChanges();
47+
48+
return entity.ToSharedDataSourceModel();
49+
}
50+
51+
public new byte[] GetByUri(string uri)
52+
{
53+
if (!uri.Contains($"{Root}\\"))
54+
{
55+
uri = $"{Root}\\{uri}";
56+
}
57+
58+
return base.GetByUri(uri);
3959
}
4060

4161

42-
ResourceFileModel SaveCore(SaveResourceModel model, byte[] resource)
62+
SharedDataSourceModel SaveCore(SaveResourceModel model, byte[] resource)
4363
{
44-
var entity = DbContext.Resources.FirstOrDefault(r => r.Uri == model.ParentUri + "\\" + model.Name);
64+
model.ParentUri = string.IsNullOrEmpty(model.ParentUri) ? "Shared Data Sources" : $"Shared Data Sources\\{model.ParentUri}";
65+
model.ParentUri = model.ParentUri.Replace("/", "\\");
66+
67+
if (model.ParentUri.EndsWith('\\'))
68+
{
69+
model.ParentUri = model.ParentUri.Remove(model.ParentUri.Length - 1);
70+
}
71+
72+
var entity = DbContext.Resources.FirstOrDefault(r => r.Uri == ResourceStorageBase.FixParentUri(model.ParentUri) + model.Name);
4573

4674
if (entity != null)
4775
{
@@ -60,5 +88,22 @@ ResourceFileModel SaveCore(SaveResourceModel model, byte[] resource)
6088

6189
return entityEntry.Entity.ToSharedDataSourceModel();
6290
}
91+
92+
SharedDataSourceModel RenameCore(RenameResourceModel model)
93+
{
94+
string oldName = model.OldUri.Split("\\").Last();
95+
var resource = DbContext.Resources.FirstOrDefault(r => r.Uri == model.OldUri);
96+
if (resource != null)
97+
{
98+
resource.Name = model.Name;
99+
resource.Uri = resource.Uri.Replace(oldName, model.Name);
100+
resource.ModifiedOn = DateTime.Now;
101+
102+
DbContext.SaveChanges();
103+
104+
return resource.ToSharedDataSourceModel();
105+
}
106+
throw new ResourceNotFoundException();
107+
}
63108
}
64109
}

SqlDefinitionStorageExample/EFCore/Models/Resource.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.ComponentModel.DataAnnotations;
33
using System.ComponentModel.DataAnnotations.Schema;
4-
using System.Runtime.InteropServices;
54

65
namespace SqlDefinitionStorageExample.EFCore.Models
76
{

SqlDefinitionStorageExample/EFCore/Models/ResourceFolder.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using Microsoft.EntityFrameworkCore;
2-
using System;
3-
using System.Collections.Generic;
1+
using System;
42
using System.ComponentModel.DataAnnotations;
53
using System.ComponentModel.DataAnnotations.Schema;
64

0 commit comments

Comments
 (0)