diff --git a/Disco.BI/BI/Extensions/DocumentTemplateExtensions.cs b/Disco.BI/BI/Extensions/DocumentTemplateExtensions.cs index 6aeb9588..b7c4dda1 100644 --- a/Disco.BI/BI/Extensions/DocumentTemplateExtensions.cs +++ b/Disco.BI/BI/Extensions/DocumentTemplateExtensions.cs @@ -6,12 +6,9 @@ using Disco.Services.Documents; using Disco.Services.Documents.ManagedGroups; using Disco.Services.Expressions; using Disco.Services.Interop.ActiveDirectory; -using Disco.Services.Tasks; using iTextSharp.text.pdf; using System; -using System.Collections.Concurrent; using System.Collections.Generic; -using System.ComponentModel; using System.Data.Entity; using System.Drawing; using System.IO; @@ -21,41 +18,58 @@ namespace Disco.BI.Extensions { public static class DocumentTemplateExtensions { - internal const string CacheTemplate = "DocumentTemplate_{0}"; - - public static ConcurrentDictionary PdfExpressionsFromCache(this DocumentTemplate dt, DiscoDataContext Database) + private static Tuple, List> CreateExpressions(DocumentTemplate dt, DiscoDataContext database) { - string cacheModuleKey = string.Format(CacheTemplate, dt.Id); - var module = ExpressionCache.GetModule(cacheModuleKey); - if (module == null) + Dictionary expressions = new Dictionary(); + List fields = new List(); + + string templateFilename = dt.RepositoryFilename(database); + PdfReader pdfReader = new PdfReader(templateFilename); + int pdfFieldOrdinal = 0; + foreach (string pdfFieldKey in pdfReader.AcroFields.Fields.Keys) { - // Cache - string templateFilename = dt.RepositoryFilename(Database); - PdfReader pdfReader = new PdfReader(templateFilename); - int pdfFieldOrdinal = 0; - foreach (string pdfFieldKey in pdfReader.AcroFields.Fields.Keys) + var pdfField = pdfReader.AcroFields.Fields[pdfFieldKey]; + var pdfFieldPositions = pdfReader.AcroFields.GetFieldPositions(pdfFieldKey); + var pdfFieldFlags = pdfField.GetMerged(0).GetAsNumber(PdfName.FF)?.IntValue ?? 0; + var isRequired = (pdfFieldFlags & 2) == 2; + var isReadOnly = (pdfFieldFlags & 1) == 1; + + var pdfFieldValue = pdfReader.AcroFields.GetField(pdfFieldKey); + var pdfFieldPosition = default(RectangleF?); + if (pdfFieldPositions != null && pdfFieldPositions.Count > 0) { - var pdfField = pdfReader.AcroFields.Fields[pdfFieldKey]; - var pdfFieldPositions = pdfReader.AcroFields.GetFieldPositions(pdfFieldKey); - var pdfFieldFlags = pdfField.GetMerged(0).GetAsNumber(PdfName.FF)?.IntValue ?? 0; - var isRequired = (pdfFieldFlags & 2) == 2; - var isReadOnly = (pdfFieldFlags & 1) == 1; - - var pdfFieldValue = pdfReader.AcroFields.GetField(pdfFieldKey); - var pdfFieldPosition = default(RectangleF?); - if (pdfFieldPositions != null && pdfFieldPositions.Count > 0) - { - var position = pdfFieldPositions.First().position; - pdfFieldPosition = new RectangleF(position.Left, position.Top, position.Width, position.Height); - } - - ExpressionCache.SetValue(cacheModuleKey, pdfFieldKey, Expression.Tokenize(pdfFieldKey, pdfFieldValue, pdfFieldOrdinal, isRequired, isReadOnly, pdfFieldPosition)); - pdfFieldOrdinal++; + var position = pdfFieldPositions.First().position; + pdfFieldPosition = new RectangleF(position.Left, position.Top, position.Width, position.Height); } - pdfReader.Close(); - module = ExpressionCache.GetModule(cacheModuleKey, true); + var fieldTypeId = pdfReader.AcroFields.GetFieldType(pdfFieldKey); + var fieldType = DocumentFieldType.None; + if (fieldTypeId <= 8 && fieldTypeId > 0) + fieldType = (DocumentFieldType)fieldTypeId; + + var fixedValues = default(List); + + if (fieldType == DocumentFieldType.RadioButton || fieldType == DocumentFieldType.Checkbox) + { + fixedValues = pdfReader.AcroFields.GetAppearanceStates(pdfFieldKey).ToList(); + } + + expressions[pdfFieldKey] = Expression.Tokenize(pdfFieldKey, pdfFieldValue, pdfFieldOrdinal, isRequired, isReadOnly, pdfFieldPosition); + fields.Add(new DocumentField(pdfFieldKey, pdfFieldValue, pdfFieldOrdinal, fieldType, isRequired, isReadOnly, fixedValues)); + pdfFieldOrdinal++; } - return module; + pdfReader.Close(); + + return Tuple.Create(expressions, fields); + } + + public static Dictionary PdfExpressionsFromCache(this DocumentTemplate dt, DiscoDataContext Database) + { + return ExpressionCache.GetOrCreateExpressions(dt, () => CreateExpressions(dt, Database)); + } + + public static List PdfFieldsFromCache(this DocumentTemplate dt, DiscoDataContext Database) + { + return ExpressionCache.GetOrCreateFields(dt, () => CreateExpressions(dt, Database)); } public static List ExtractPdfExpressions(this DocumentTemplate dt, DiscoDataContext Database) diff --git a/Disco.BI/BI/Interop/Pdf/PdfGenerator.cs b/Disco.BI/BI/Interop/Pdf/PdfGenerator.cs index 3d8de4fa..13c9f12e 100644 --- a/Disco.BI/BI/Interop/Pdf/PdfGenerator.cs +++ b/Disco.BI/BI/Interop/Pdf/PdfGenerator.cs @@ -214,7 +214,7 @@ namespace Disco.BI.Interop.Pdf if (dt.FlattenForm) FlattenFields = true; - ConcurrentDictionary expressionCache = dt.PdfExpressionsFromCache(Database); + var expressionCache = dt.PdfExpressionsFromCache(Database); string templateFilename = dt.RepositoryFilename(Database); PdfReader pdfReader = new PdfReader(templateFilename); diff --git a/Disco.Models/Disco.Models.csproj b/Disco.Models/Disco.Models.csproj index aff4bf69..2904bef0 100644 --- a/Disco.Models/Disco.Models.csproj +++ b/Disco.Models/Disco.Models.csproj @@ -68,6 +68,8 @@ + + diff --git a/Disco.Models/Services/Documents/DocumentField.cs b/Disco.Models/Services/Documents/DocumentField.cs new file mode 100644 index 00000000..9ee55823 --- /dev/null +++ b/Disco.Models/Services/Documents/DocumentField.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; + +namespace Disco.Models.Services.Documents +{ + public class DocumentField + { + public string Name { get; } + public string Value { get; } + public int Ordinal { get; } + + public DocumentFieldType Type { get; } + public bool IsRequired { get; } + public bool IsReadOnly { get; } + + public List FixedValues { get; } + + public DocumentField(string name, string value, int ordinal, DocumentFieldType type, bool isRequired, bool isReadOnly, List fixedValues) + { + Name = name; + Value = value; + Ordinal = ordinal; + Type = type; + IsRequired = isRequired; + IsReadOnly = isReadOnly; + FixedValues = fixedValues; + } + } +} diff --git a/Disco.Models/Services/Documents/DocumentFieldType.cs b/Disco.Models/Services/Documents/DocumentFieldType.cs new file mode 100644 index 00000000..2c7c7894 --- /dev/null +++ b/Disco.Models/Services/Documents/DocumentFieldType.cs @@ -0,0 +1,14 @@ +namespace Disco.Models.Services.Documents +{ + public enum DocumentFieldType + { + None = 0, + PushButton = 1, + Checkbox = 2, + RadioButton = 3, + Text = 4, + List = 5, + Combo = 6, + Signature = 7, + } +} diff --git a/Disco.Services/Devices/DeviceExtensions.cs b/Disco.Services/Devices/DeviceExtensions.cs index 35e288c9..c75d867d 100644 --- a/Disco.Services/Devices/DeviceExtensions.cs +++ b/Disco.Services/Devices/DeviceExtensions.cs @@ -21,12 +21,8 @@ namespace Disco.Services var deviceProfile = device.DeviceProfile; Expression computerNameTemplateExpression = null; - computerNameTemplateExpression = ExpressionCache.GetValue(DeviceProfileExtensions.ComputerNameExpressionCacheModule, deviceProfile.Id.ToString(), () => - { - // Removed 2012-06-14 G# - Properties moved to DeviceProfile model & DB Migrated in DBv3. - //return Expressions.Expression.TokenizeSingleDynamic(null, deviceProfile.Configuration(context).ComputerNameTemplate, 0); - return Expression.TokenizeSingleDynamic(null, deviceProfile.ComputerNameTemplate, 0); - }); + computerNameTemplateExpression = ExpressionCache.GetOrCreateSingleExpressions(string.Format(DeviceProfileExtensions.ComputerNameExpressionCacheTemplate, deviceProfile.Id), + () => Expression.TokenizeSingleDynamic(null, deviceProfile.ComputerNameTemplate, 0)); var evaluatorVariables = Expression.StandardVariables(null, Database, UserService.CurrentUser, DateTime.Now, null, device); string rendered; try diff --git a/Disco.Services/Devices/DeviceProfileExtensions.cs b/Disco.Services/Devices/DeviceProfileExtensions.cs index 714a666c..9cbdda62 100644 --- a/Disco.Services/Devices/DeviceProfileExtensions.cs +++ b/Disco.Services/Devices/DeviceProfileExtensions.cs @@ -18,11 +18,11 @@ namespace Disco.Services { public static class DeviceProfileExtensions { - public const string ComputerNameExpressionCacheModule = "ComputerNameTemplate"; + public const string ComputerNameExpressionCacheTemplate = "ComputerNameTemplate_{0}"; public static void ComputerNameInvalidateCache(this DeviceProfile deviceProfile) { - ExpressionCache.InvalidateKey(ComputerNameExpressionCacheModule, deviceProfile.Id.ToString()); + ExpressionCache.InvalidateSingleCache(string.Format(ComputerNameExpressionCacheTemplate, deviceProfile.Id)); } public static OrganisationAddress DefaultOrganisationAddressDetails(this DeviceProfile deviceProfile, DiscoDataContext Database) diff --git a/Disco.Services/Documents/DocumentTemplateDataStoreExtensions.cs b/Disco.Services/Documents/DocumentTemplateDataStoreExtensions.cs index 93883c3e..e99a3f7b 100644 --- a/Disco.Services/Documents/DocumentTemplateDataStoreExtensions.cs +++ b/Disco.Services/Documents/DocumentTemplateDataStoreExtensions.cs @@ -8,8 +8,9 @@ namespace Disco.Services { public static string RepositoryFilename(this DocumentTemplate dt, DiscoDataContext Database) { - return Path.Combine(DataStore.CreateLocation(Database, "DocumentTemplates"), string.Format("{0}.pdf", dt.Id)); + return Path.Combine(DataStore.CreateLocation(Database, "DocumentTemplates"), $"{dt.Id}.pdf"); } + public static string SavePdfTemplate(this DocumentTemplate dt, DiscoDataContext Database, Stream TemplateFile) { string filePath = dt.RepositoryFilename(Database); @@ -17,7 +18,7 @@ namespace Disco.Services { TemplateFile.CopyTo(fs); } - Expressions.ExpressionCache.InvalidModule(string.Format(DocumentTemplateExpressionExtensions.CacheTemplate, dt.Id)); + Expressions.ExpressionCache.InvalidateCache(dt); return filePath; } } diff --git a/Disco.Services/Documents/DocumentTemplateExpressionExtensions.cs b/Disco.Services/Documents/DocumentTemplateExpressionExtensions.cs index d10b8ad4..11f2004a 100644 --- a/Disco.Services/Documents/DocumentTemplateExpressionExtensions.cs +++ b/Disco.Services/Documents/DocumentTemplateExpressionExtensions.cs @@ -10,19 +10,17 @@ namespace Disco.Services { public static class DocumentTemplateExpressionExtensions { - internal const string CacheTemplate = "DocumentTemplate_{0}"; - public static Expression FilterExpressionFromCache(this DocumentTemplate dt) { - return ExpressionCache.GetValue("DocumentTemplate_FilterExpression", dt.Id, () => { return Expression.TokenizeSingleDynamic(null, dt.FilterExpression, 0); }); + return ExpressionCache.GetOrCreateSingleExpressions($"DocumentTemplate_FilterExpression_{dt.Id}", () => Expression.TokenizeSingleDynamic(null, dt.FilterExpression, 0)); } public static void FilterExpressionInvalidateCache(this DocumentTemplate dt) { - ExpressionCache.InvalidateKey("DocumentTemplate_FilterExpression", dt.Id); + ExpressionCache.InvalidateSingleCache($"DocumentTemplate_FilterExpression_{dt.Id}"); } - public static bool FilterExpressionMatches(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, System.DateTime TimeStamp, DocumentState State) + public static bool FilterExpressionMatches(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State) { if (!string.IsNullOrEmpty(dt.FilterExpression)) { @@ -51,12 +49,12 @@ namespace Disco.Services public static Expression OnImportAttachmentExpressionFromCache(this DocumentTemplate dt) { - return ExpressionCache.GetValue("DocumentTemplate_OnImportExpression", dt.Id, () => { return Expression.TokenizeSingleDynamic(null, dt.OnImportAttachmentExpression, 0); }); + return ExpressionCache.GetOrCreateSingleExpressions($"DocumentTemplate_OnImportExpression_{dt.Id}", () => Expression.TokenizeSingleDynamic(null, dt.OnImportAttachmentExpression, 0)); } public static void OnImportAttachmentExpressionInvalidateCache(this DocumentTemplate dt) { - ExpressionCache.InvalidateKey("DocumentTemplate_OnImportExpression", dt.Id); + ExpressionCache.InvalidateSingleCache($"DocumentTemplate_OnImportExpression_{dt.Id}"); } public static string EvaluateOnAttachmentImportExpression(this DocumentTemplate dt, IAttachment Data, IAttachmentTarget AttachmentTarget, DiscoDataContext Database, User User, DateTime TimeStamp, List PageIdentifiers) @@ -77,12 +75,12 @@ namespace Disco.Services public static Expression OnGenerateExpressionFromCache(this DocumentTemplate dt) { - return ExpressionCache.GetValue("DocumentTemplate_OnGenerateExpression", dt.Id, () => { return Expression.TokenizeSingleDynamic(null, dt.OnGenerateExpression, 0); }); + return ExpressionCache.GetOrCreateSingleExpressions($"DocumentTemplate_OnGenerateExpression_{dt.Id}", () => Expression.TokenizeSingleDynamic(null, dt.OnGenerateExpression, 0)); } public static void OnGenerateExpressionInvalidateCache(this DocumentTemplate dt) { - ExpressionCache.InvalidateKey("DocumentTemplate_OnGenerateExpression", dt.Id); + ExpressionCache.InvalidateSingleCache($"DocumentTemplate_OnGenerateExpression_{dt.Id}"); } public static string EvaluateOnGenerateExpression(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State) diff --git a/Disco.Services/Documents/DocumentTemplatePackageExtensions.cs b/Disco.Services/Documents/DocumentTemplatePackageExtensions.cs index 37dd55a1..3da777df 100644 --- a/Disco.Services/Documents/DocumentTemplatePackageExtensions.cs +++ b/Disco.Services/Documents/DocumentTemplatePackageExtensions.cs @@ -73,12 +73,12 @@ namespace Disco.Services public static Expression FilterExpressionFromCache(this DocumentTemplatePackage package) { - return ExpressionCache.GetValue("DocumentTemplatePackage_FilterExpression", package.Id, () => { return Expression.TokenizeSingleDynamic(null, package.FilterExpression, 0); }); + return ExpressionCache.GetOrCreateSingleExpressions($"DocumentTemplatePackage_FilterExpression_{package.Id}", () => Expression.TokenizeSingleDynamic(null, package.FilterExpression, 0)); } public static void FilterExpressionInvalidateCache(this DocumentTemplatePackage package) { - ExpressionCache.InvalidateKey("DocumentTemplatePackage_FilterExpression", package.Id); + ExpressionCache.InvalidateSingleCache($"DocumentTemplatePackage_FilterExpression_{package.Id}"); } public static bool FilterExpressionMatches(this DocumentTemplatePackage package, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State) @@ -111,12 +111,12 @@ namespace Disco.Services public static Expression OnGenerateExpressionFromCache(this DocumentTemplatePackage package) { - return ExpressionCache.GetValue("DocumentTemplatePackage_OnGenerateExpression", package.Id, () => { return Expression.TokenizeSingleDynamic(null, package.OnGenerateExpression, 0); }); + return ExpressionCache.GetOrCreateSingleExpressions($"DocumentTemplatePackage_OnGenerateExpression_{package.Id}", () => Expression.TokenizeSingleDynamic(null, package.OnGenerateExpression, 0)); } public static void OnGenerateExpressionInvalidateCache(this DocumentTemplatePackage package) { - ExpressionCache.InvalidateKey("DocumentTemplatePackage_OnGenerateExpression", package.Id); + ExpressionCache.InvalidateSingleCache($"DocumentTemplatePackage_OnGenerateExpression_{package.Id}"); } public static string EvaluateOnGenerateExpression(this DocumentTemplatePackage package, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State) diff --git a/Disco.Services/Expressions/Expression.cs b/Disco.Services/Expressions/Expression.cs index 4eec93af..251a2a64 100644 --- a/Disco.Services/Expressions/Expression.cs +++ b/Disco.Services/Expressions/Expression.cs @@ -9,7 +9,6 @@ using System; using System.Collections; using System.Collections.Generic; using System.Drawing; -using System.Linq; using System.Text; namespace Disco.Services.Expressions diff --git a/Disco.Services/Expressions/ExpressionCache.cs b/Disco.Services/Expressions/ExpressionCache.cs index f99a305d..3ed2af59 100644 --- a/Disco.Services/Expressions/ExpressionCache.cs +++ b/Disco.Services/Expressions/ExpressionCache.cs @@ -1,99 +1,83 @@ -using System.Collections.Concurrent; +using Disco.Models.Repository; +using Disco.Models.Services.Documents; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; namespace Disco.Services.Expressions { public static class ExpressionCache { - private static ConcurrentDictionary> _Cache = new ConcurrentDictionary>(); + private static ConcurrentDictionary singleCache = new ConcurrentDictionary(); + private static ConcurrentDictionary> cache = new ConcurrentDictionary>(); + private static ConcurrentDictionary> fieldCache = new ConcurrentDictionary>(); - public delegate Expression CreateValueDelegate(); + private const string DocumentTemplateCacheTemplate = "DocumentTemplate_{0}"; - public static ConcurrentDictionary GetModule(string Module, bool Create = false) + public static Expression GetOrCreateSingleExpressions(string key, Func create) { - ConcurrentDictionary moduleCache; - if (_Cache.TryGetValue(Module, out moduleCache)) - return moduleCache; + if (singleCache.TryGetValue(key, out var result)) + return result; else { - if (Create) - { - moduleCache = new ConcurrentDictionary(); - _Cache.TryAdd(Module, moduleCache); - return moduleCache; - } - else - return null; + result = create(); + singleCache.TryAdd(key, result); + return result; } } - private static Expression GetModuleValue(string Module, string Key, CreateValueDelegate CreateValue) - { - ConcurrentDictionary moduleCache = GetModule(Module, (CreateValue != null)); - if (moduleCache != null) - { - Expression expression; - if (moduleCache.TryGetValue(Key, out expression)) - { - return expression; - } - if (CreateValue != null) - { - expression = CreateValue(); - Expression oldExpression; - if (moduleCache.TryGetValue(Key, out oldExpression)) - moduleCache.TryUpdate(Key, expression, oldExpression); - else - moduleCache.TryAdd(Key, expression); - return expression; - } - } - return null; - } - public static Expression GetValue(string Module, string Key, CreateValueDelegate CreateValue) + public static Dictionary GetOrCreateExpressions(string module, Func, List>> create) { - return GetModuleValue(Module, Key, CreateValue); - } - - public static Expression GetValue(string Module, string Key) - { - return GetModuleValue(Module, Key, null); - } - - public static bool InvalidModule(string Module) - { - ConcurrentDictionary moduleCache; - return _Cache.TryRemove(Module, out moduleCache); - } - - public static bool InvalidateKey(string Module, string Key) - { - Expression expression; - ConcurrentDictionary moduleCache = GetModule(Module, false); - if (moduleCache != null) - { - bool removeResult = moduleCache.TryRemove(Key, out expression); - if (moduleCache.Count == 0) - InvalidModule(Module); - return removeResult; - } + if (cache.TryGetValue(module, out var result)) + return result; else - return false; - } - - public static bool SetValue(string Module, string Key, Expression Expression) - { - ConcurrentDictionary moduleCache = GetModule(Module, true); - - if (moduleCache.ContainsKey(Key)) { - Expression oldExpression; - if (moduleCache.TryGetValue(Key, out oldExpression)) - { - return moduleCache.TryUpdate(Key, Expression, oldExpression); - } + return Create(module, create).Item1; } - return moduleCache.TryAdd(Key, Expression); } + public static List GetOrCreateFields(string module, Func, List>> create) + { + if (fieldCache.TryGetValue(module, out var result)) + return result; + else + { + return Create(module, create).Item2; + } + } + + public static void InvalidateCache(DocumentTemplate template) + { + InvalidateCache(string.Format(DocumentTemplateCacheTemplate, template.Id)); + } + + public static void InvalidateCache(string module) + { + cache.TryRemove(module, out _); + fieldCache.TryRemove(module, out _); + } + + public static void InvalidateSingleCache(string key) + { + singleCache.TryRemove(key, out _); + } + + public static Dictionary GetOrCreateExpressions(DocumentTemplate template, Func, List>> create) + { + return GetOrCreateExpressions(string.Format(DocumentTemplateCacheTemplate, template.Id), create); + } + + public static List GetOrCreateFields(DocumentTemplate template, Func, List>> create) + { + return GetOrCreateFields(string.Format(DocumentTemplateCacheTemplate, template.Id), create); + } + + private static Tuple, List> Create(string module, Func, List>> create) + { + var results = create(); + cache.TryAdd(module, results.Item1); + fieldCache.TryAdd(module, results.Item2); + return results; + } } } diff --git a/Disco.Services/Jobs/Jobs.cs b/Disco.Services/Jobs/Jobs.cs index 558ab40f..0a3194dc 100644 --- a/Disco.Services/Jobs/Jobs.cs +++ b/Disco.Services/Jobs/Jobs.cs @@ -123,22 +123,22 @@ namespace Disco.Services.Jobs public static Expression OnCreateExpressionFromCache(DiscoDataContext Database) { - return ExpressionCache.GetValue("Job_OnCreateExpression", string.Empty, () => { return Expression.TokenizeSingleDynamic(null, Database.DiscoConfiguration.JobPreferences.OnCreateExpression, 0); }); + return ExpressionCache.GetOrCreateSingleExpressions("Job_OnCreateExpression", () => Expression.TokenizeSingleDynamic(null, Database.DiscoConfiguration.JobPreferences.OnCreateExpression, 0)); } public static void OnCreateExpressionInvalidateCache() { - ExpressionCache.InvalidateKey("Job_OnCreateExpression", string.Empty); + ExpressionCache.InvalidateSingleCache("Job_OnCreateExpression"); } public static Expression OnCloseExpressionFromCache(DiscoDataContext Database) { - return ExpressionCache.GetValue("Job_OnCloseExpression", string.Empty, () => { return Expression.TokenizeSingleDynamic(null, Database.DiscoConfiguration.JobPreferences.OnCloseExpression, 0); }); + return ExpressionCache.GetOrCreateSingleExpressions("Job_OnCloseExpression", () => Expression.TokenizeSingleDynamic(null, Database.DiscoConfiguration.JobPreferences.OnCloseExpression, 0)); } public static void OnCloseExpressionInvalidateCache() { - ExpressionCache.InvalidateKey("Job_OnCloseExpression", string.Empty); + ExpressionCache.InvalidateSingleCache("Job_OnCloseExpression"); } } diff --git a/Disco.Services/Users/UserFlags/UserFlagExtensions.cs b/Disco.Services/Users/UserFlags/UserFlagExtensions.cs index ba73e46b..f39e2e33 100644 --- a/Disco.Services/Users/UserFlags/UserFlagExtensions.cs +++ b/Disco.Services/Users/UserFlags/UserFlagExtensions.cs @@ -133,12 +133,12 @@ namespace Disco.Services public static Expression OnAssignmentExpressionFromCache(this UserFlag uf) { - return ExpressionCache.GetValue("UserFlag_OnAssignmentExpression", uf.Id.ToString(), () => { return Expression.TokenizeSingleDynamic(null, uf.OnAssignmentExpression, 0); }); + return ExpressionCache.GetOrCreateSingleExpressions($"UserFlag_OnAssignmentExpression_{uf.Id}", () => Expression.TokenizeSingleDynamic(null, uf.OnAssignmentExpression, 0)); } public static void OnAssignmentExpressionInvalidateCache(this UserFlag uf) { - ExpressionCache.InvalidateKey("UserFlag_OnAssignmentExpression", uf.Id.ToString()); + ExpressionCache.InvalidateSingleCache($"UserFlag_OnAssignmentExpression_{uf.Id}"); } public static string EvaluateOnAssignmentExpression(this UserFlagAssignment ufa, DiscoDataContext Database, User AddingUser, DateTime TimeStamp) @@ -158,12 +158,12 @@ namespace Disco.Services public static Expression OnUnassignmentExpressionFromCache(this UserFlag uf) { - return ExpressionCache.GetValue("UserFlag_OnUnassignmentExpression", uf.Id.ToString(), () => { return Expression.TokenizeSingleDynamic(null, uf.OnUnassignmentExpression, 0); }); + return ExpressionCache.GetOrCreateSingleExpressions($"UserFlag_OnUnassignmentExpression_{uf.Id}", () => Expression.TokenizeSingleDynamic(null, uf.OnUnassignmentExpression, 0)); } public static void OnUnassignmentExpressionInvalidateCache(this UserFlag uf) { - ExpressionCache.InvalidateKey("UserFlag_OnUnassignmentExpression", uf.Id.ToString()); + ExpressionCache.InvalidateSingleCache($"UserFlag_OnUnassignmentExpression_{uf.Id}"); } public static string EvaluateOnUnassignmentExpression(this UserFlagAssignment ufa, DiscoDataContext Database, User RemovingUser, DateTime TimeStamp) diff --git a/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs b/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs index a60f1c05..e3a6458b 100644 --- a/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs +++ b/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs @@ -1231,6 +1231,8 @@ namespace Disco.Web.Areas.API.Controllers } } + [HttpPost, ValidateAntiForgeryToken] + [DiscoAuthorizeAll(Claims.Config.DocumentTemplate.Configure, Claims.Config.UserFlag.Configure)] public virtual ActionResult AddOnImportUserFlagRule([Required] string id, bool? addFlag = null, int? userFlagId = null, string comments = null) { try