Bug Report T1147608
Visible to All Users
Duplicate

Security.Blazor - The "ValueManagerContext.Storage is null" error occurs on downloading a file attachment with CurrentUserId() in PersistentAlias

created 2 years ago (modified 2 years ago)

The error occurs when a custom File Attachment class has a PersistentAlias property with the CurrentUserId function in its expression, and this property is used in Object Permissions.

C#
[FileAttachment("File")] public class UserFileAttachment : BaseObject { //... [PersistentAlias("Owner.Oid = CurrentUserId()")] public bool IsCurrentUser { get { return (bool)EvaluateAlias(nameof(IsCurrentUser)); } } } public class Updater : ModuleUpdater { public override void UpdateDatabaseAfterUpdateSchema() { //... defaultRole.AddObjectPermissionFromLambda<UserFileAttachment>(SecurityOperations.Read, f => !f.IsCurrentUser, SecurityPermissionState.Deny); //... } }

Steps to reproduce

  1. Run the attached project.
  2. Log in as 'User'.
  3. Go to My Details.
  4. Add a file to the Files collection.
  5. Download this file.

Current behavior

The file is not downloaded. The application throws the following exception:

System.InvalidOperationException: 'ValueManagerContext.Storage is null.'

Call Stack
DevExpress.ExpressApp.AspNetCore.v22.2.dll!DevExpress.ExpressApp.Blazor.AmbientContext.AspNetCoreValueManager<DevExpress.ExpressApp.Security.ISecurityStrategyBase>.CheckPossibleDeploymentIssues() Line 60 C# DevExpress.ExpressApp.AspNetCore.v22.2.dll!DevExpress.ExpressApp.Blazor.AmbientContext.AspNetCoreValueManager<DevExpress.ExpressApp.Security.ISecurityStrategyBase>.EnsureStorage() Line 55 C# DevExpress.ExpressApp.AspNetCore.v22.2.dll!DevExpress.ExpressApp.Blazor.AmbientContext.AspNetCoreValueManager<DevExpress.ExpressApp.Security.ISecurityStrategyBase>.Value.get() Line 52 C# DevExpress.ExpressApp.v22.2.dll!DevExpress.ExpressApp.SecuritySystem.Instance.get() Line 172 C# DevExpress.ExpressApp.v22.2.dll!DevExpress.ExpressApp.SecuritySystem.CurrentUserId.get() Line 177 C# DevExpress.ExpressApp.v22.2.dll!DevExpress.ExpressApp.SystemModule.CurrentUserIdOperator.Evaluate(object[] operands) Line 54 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.Helpers.ExpressionEvaluator.EvaluateCustomFunction(string functionName, object[] operands) Line 1404 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.Helpers.ExpressionEvaluatorCoreBase.FnCustom(DevExpress.Data.Filtering.FunctionOperator theOperator) Line 763 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.Helpers.ExpressionEvaluatorCoreBase.Visit(DevExpress.Data.Filtering.FunctionOperator theOperator) Line 666 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.FunctionOperator.Accept<object>(DevExpress.Data.Filtering.ICriteriaVisitor<object> visitor) Line 2800 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.Helpers.ExpressionEvaluatorCoreBase.Process(DevExpress.Data.Filtering.CriteriaOperator operand) Line 527 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.Helpers.ExpressionEvaluatorCoreBase.Evaluate(DevExpress.Data.Filtering.Helpers.EvaluatorContext evaluationContext, DevExpress.Data.Filtering.CriteriaOperator evaluatorCriteria, System.Collections.IComparer customComparer) Line 1144 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.Helpers.ExpressionEvaluator.Evaluate(object theObject, System.Collections.IComparer customComparer) Line 1321 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.Helpers.ExpressionEvaluator.Evaluate(object theObject) Line 1318 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.UnknownCriteriaEleminatorBase.Evaluate(DevExpress.Data.Filtering.CriteriaOperator theOperator) Line 588 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.UnknownCriteriaEleminatorBase.Visit(DevExpress.Data.Filtering.FunctionOperator theOperator) Line 344 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.PersistentCriterionExpander.Visit(DevExpress.Data.Filtering.FunctionOperator theOperator) Line 1212 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.StronglyTypedCriteriaVisitorBase<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>.DevExpress.Data.Filtering.ICriteriaVisitor<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>.Visit(DevExpress.Data.Filtering.FunctionOperator theOperator) Line 120 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.FunctionOperator.Accept<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>(DevExpress.Data.Filtering.ICriteriaVisitor<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder> visitor) Line 2800 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.UnknownCriteriaEleminatorBase.Process(DevExpress.Data.Filtering.CriteriaOperator operand) Line 583 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.UnknownCriteriaEleminatorBase.Visit(DevExpress.Data.Filtering.BinaryOperator theOperator) Line 527 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.PersistentCriterionExpander.Visit(DevExpress.Data.Filtering.BinaryOperator theOperator) Line 706 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.StronglyTypedCriteriaVisitorBase<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>.DevExpress.Data.Filtering.ICriteriaVisitor<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>.Visit(DevExpress.Data.Filtering.BinaryOperator theOperator) Line 135 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.BinaryOperator.Accept<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>(DevExpress.Data.Filtering.ICriteriaVisitor<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder> visitor) Line 2535 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.UnknownCriteriaEleminatorBase.Process(DevExpress.Data.Filtering.CriteriaOperator operand) Line 583 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.PersistentCriterionExpander.Expand(DevExpress.Xpo.Metadata.XPClassInfo[] upLevels, DevExpress.Xpo.Helpers.IPersistentValueExtractor persistentValuesSource, DevExpress.Data.Filtering.CriteriaOperator op, int aliasDepthWatchDog, bool doDetectPostProcessing) Line 1153 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.PersistentCriterionExpander.ProcessInContext(DevExpress.Xpo.Metadata.XPClassInfo[] upLevels, DevExpress.Data.Filtering.CriteriaOperator operand) Line 1150 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.PersistentCriterionExpander.Visit(DevExpress.Data.Filtering.OperandProperty theOriginalOperand) Line 928 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.StronglyTypedCriteriaVisitorBase<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>.DevExpress.Data.Filtering.IClientCriteriaVisitor<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>.Visit(DevExpress.Data.Filtering.OperandProperty theOperand) Line 111 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.OperandProperty.Accept<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>(DevExpress.Data.Filtering.ICriteriaVisitor<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder> visitor) Line 1871 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.UnknownCriteriaEleminatorBase.Process(DevExpress.Data.Filtering.CriteriaOperator operand) Line 583 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.UnknownCriteriaEleminatorBase.Visit(DevExpress.Data.Filtering.UnaryOperator theOperator) Line 492 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.StronglyTypedCriteriaVisitorBase<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>.DevExpress.Data.Filtering.ICriteriaVisitor<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>.Visit(DevExpress.Data.Filtering.UnaryOperator theOperator) Line 132 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.UnaryOperator.Accept<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>(DevExpress.Data.Filtering.ICriteriaVisitor<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder> visitor) Line 2681 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.UnknownCriteriaEleminatorBase.Process(DevExpress.Data.Filtering.CriteriaOperator operand) Line 583 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.UnknownCriteriaEleminatorBase.Visit(DevExpress.Data.Filtering.UnaryOperator theOperator) Line 492 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.StronglyTypedCriteriaVisitorBase<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>.DevExpress.Data.Filtering.ICriteriaVisitor<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>.Visit(DevExpress.Data.Filtering.UnaryOperator theOperator) Line 132 C# DevExpress.Data.v22.2.dll!DevExpress.Data.Filtering.UnaryOperator.Accept<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder>(DevExpress.Data.Filtering.ICriteriaVisitor<DevExpress.Xpo.Helpers.ExpandedCriteriaHolder> visitor) Line 2681 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.UnknownCriteriaEleminatorBase.Process(DevExpress.Data.Filtering.CriteriaOperator operand) Line 583 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.PersistentCriterionExpander.Expand(DevExpress.Xpo.Metadata.XPClassInfo[] upLevels, DevExpress.Xpo.Helpers.IPersistentValueExtractor persistentValuesSource, DevExpress.Data.Filtering.CriteriaOperator op, int aliasDepthWatchDog, bool doDetectPostProcessing) Line 1153 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.PersistentCriterionExpander.Expand(DevExpress.Xpo.Metadata.XPClassInfo[] upLevels, DevExpress.Xpo.Helpers.IPersistentValueExtractor persistentValuesSource, DevExpress.Data.Filtering.CriteriaOperator op, bool doDetectPostProcessing) Line 1156 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.PersistentCriterionExpander.Expand(DevExpress.Xpo.Metadata.XPClassInfo ci, DevExpress.Xpo.Helpers.IPersistentValueExtractor persistentValuesSource, DevExpress.Data.Filtering.CriteriaOperator op, bool doDetectPostProcessing) Line 1197 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.PersistentCriterionExpander.Expand(DevExpress.Xpo.Helpers.IPersistentValueExtractor persistentValuesSource, DevExpress.Xpo.Metadata.XPClassInfo ci, DevExpress.Data.Filtering.CriteriaOperator op, bool doDetectPostProcessing) Line 1203 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.SecurityContext.Expand(DevExpress.Xpo.Metadata.XPClassInfo classInfo, DevExpress.Data.Filtering.CriteriaOperator op) Line 159 C# DevExpress.ExpressApp.Security.Xpo.v22.2.dll!DevExpress.ExpressApp.Security.ClientServer.SecurityRule2.GetSelectMemberExpression(DevExpress.Xpo.SecurityContext context, DevExpress.Xpo.Metadata.XPClassInfo classInfo, DevExpress.Xpo.Metadata.XPMemberInfo memberInfo, out DevExpress.Data.Filtering.CriteriaOperator expression) Line 354 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.SecurityContext.GetSelectMemberExpression(DevExpress.Xpo.ISecurityRule2 rule, DevExpress.Xpo.Metadata.XPClassInfo ci, DevExpress.Xpo.Metadata.XPMemberInfo mi, out DevExpress.Data.Filtering.CriteriaOperator memberExpression) Line 200 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.SecurityContext.GetSelectMemberExpression(DevExpress.Xpo.Metadata.XPClassInfo ci, DevExpress.Xpo.Metadata.XPMemberInfo mi, out DevExpress.Data.Filtering.CriteriaOperator memberExpression) Line 220 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.NestedLoader.GetProcessedGroup(DevExpress.Xpo.Metadata.XPClassInfo classInfo, System.Collections.Generic.IDictionary<DevExpress.Xpo.Metadata.XPClassInfo, DevExpress.Xpo.Helpers.NestedLoader.ObjectGroup> processed) Line 249 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.NestedLoader.BeginCloneObjects(DevExpress.Xpo.Helpers.ObjectDictionary<object> processedPairs, System.Collections.Generic.List<object> toFireLoaded, System.Collections.Generic.IDictionary<DevExpress.Xpo.Metadata.XPClassInfo, DevExpress.Xpo.Helpers.NestedLoader.ObjectGroup> processed) Line 236 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.NestedLoader.BeginProcessParentObjectsForGetNestedObjectsCore(System.Collections.ICollection[] parentObjects, bool[] force, DevExpress.Xpo.Helpers.ObjectDictionary<object> processedPairs, System.Collections.Generic.List<object> toFireLoaded, System.Collections.Generic.IDictionary<DevExpress.Xpo.Metadata.XPClassInfo, DevExpress.Xpo.Helpers.NestedLoader.ObjectGroup> processed) Line 579 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.NestedLoader.BeginProcessParentObjectsForGetNestedObjects(System.Collections.ICollection[] parentObjects, bool[] force, DevExpress.Xpo.Helpers.ObjectDictionary<object> processedPairs, System.Collections.Generic.List<object> toFireLoaded, System.Collections.Generic.IDictionary<DevExpress.Xpo.Metadata.XPClassInfo, DevExpress.Xpo.Helpers.NestedLoader.ObjectGroup> processed) Line 547 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.NestedLoader.ProcessParentObjectsForGetNestedObjects(System.Collections.ICollection[] parentObjects, bool[] force, System.Collections.Generic.List<object> outObjectsToFireLoaded) Line 510 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.NestedLoader.GetNestedObjectsCore(System.Collections.ICollection[] parentObjects, bool[] force, System.Collections.Generic.List<object> outObjectsToFireLoaded) Line 497 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Helpers.NestedLoader.GetNestedObjects(System.Collections.ICollection[] parentObjects, bool[] force) Line 473 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.SessionObjectLayer.GetObjectsByKey(DevExpress.Xpo.Session session, DevExpress.Xpo.ObjectsByKeyQuery[] queries) Line 956 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Session.GetObjectByKey.AnonymousMethod__0() Line 3015 C# DevExpress.Data.v22.2.dll!DevExpress.Xpo.Logger.LogManager.Log<object>(string category, DevExpress.Xpo.Logger.LogManager.LogHandler<object> handler, DevExpress.Xpo.Logger.LogManager.MessageHandler<DevExpress.Xpo.Logger.LogMessage> createMessageHandler) Line 199 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Session.GetObjectByKey(DevExpress.Xpo.Metadata.XPClassInfo classInfo, object id, bool alwaysGetFromDataStore) Line 3006 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Session.GetObjectByKey(DevExpress.Xpo.Metadata.XPClassInfo classInfo, object id) Line 2787 C# DevExpress.Xpo.v22.2.dll!DevExpress.Xpo.Session.GetObjectByKey(System.Type classType, object id) Line 2784 C# DevExpress.ExpressApp.Xpo.v22.2.dll!DevExpress.ExpressApp.Xpo.XPObjectSpace.GetObjectByKey(System.Type objectType, object key) Line 686 C# DevExpress.ExpressApp.AspNetCore.v22.2.dll!DevExpress.ExpressApp.AspNetCore.Streaming.StreamService.GetFileStream(DevExpress.ExpressApp.DC.ITypeInfo typeInfo, string objectKey, string propertyName) Line 77 C# DevExpress.ExpressApp.Blazor.v22.2.dll!DevExpress.ExpressApp.AspNetCore.Streaming.FileService.GetFileStream(string objectType, string objectKey, string propertyName) Line 66 C# DevExpress.ExpressApp.Blazor.v22.2.dll!DevExpress.ExpressApp.AspNetCore.Streaming.FileService.GetFile(string objectType, string objectKey, string propertyName) Line 60 C# DevExpress.ExpressApp.Blazor.v22.2.dll!DevExpress.ExpressApp.Blazor.Services.FileDataResourcesMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context, DevExpress.ExpressApp.AspNetCore.Streaming.IFileService fileService) Line 94 C#

Workaround

Replace PersistentAlias properties with their expressions in Object and Member permissions:

C#
//defaultRole.AddObjectPermissionFromLambda<UserFileAttachment>(SecurityOperations.Read, f => !f.IsCurrentUser, SecurityPermissionState.Deny); defaultRole.AddObjectPermissionFromLambda<UserFileAttachment>(SecurityOperations.Read, f => f.Owner.Oid != (Guid)CurrentUserIdOperator.CurrentUserId(), SecurityPermissionState.Deny);
Comments (2)
Dmitry M (DevExpress) 2 years ago

    Hello,

    An additional workaround without changing a criterion is applicable to the FileService service. You can use the solution with a custom IObjectSpaceFactoryWrapper instance described here: T1120269 - Urgent: ValueManagerContext.Storage is null in 22.1.5.

    Dmitry M (DevExpress) 2 years ago

      I created a separate ticket for further investigation and discussion: T1147982 - Security.Blazor - "ValueManagerContext.Storage is null" error occurs when a custom function criteria operator is not processed by the SecurityFunctionPatcher logic. We will publish all further updates there.

      Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

      Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.