OData / AspNetCoreOData

ASP.NET Core OData: A server library built upon ODataLib and ASP.NET Core
Other
453 stars 160 forks source link

8.0.3 fails with error Value cannot be null. (Parameter 'structuredType') . May be because Autoexpand and EnableQuery Conflicts #436

Open kapilratra02 opened 2 years ago

kapilratra02 commented 2 years ago

Short summary (3-5 sentences) describing the issue.

If we use ENableQuery Attribute in our controller Action method defined as part of .netcore. Error comes that Value cannot be null. (Parameter 'structuredType') . The reason seems Enable Query and AutoExpand are not working if both are present. in 8.0.3

Assemblies affected

*Which assemblies and versions are known to be affected microsoft.aspnetcore.odata\8.0.3\lib\netcoreapp3.1\Microsoft.AspNetCore.OData.dll

Reproduce steps

The simplest set of steps to reproduce the issue. If possible, reference a commit that demonstrates the issue.

We have an GttpGet action in the controller defined EnableQuery and it returns Ilist

Now if we remove the EnableQuery. The get operation works. Also if we remove [AutoExpand] expand attribute then also it works.

But we want to keep both attributes. The error which pops out is "Value cannot be null. (Parameter 'structuredType')"

We have below Contracts:

     public abstract class DataSource 
     {
        /// <summary>
        /// Gets or sets the ID of the item.
        /// </summary>
        [DataMember(Name = "id")]
        [ReadOnly(true)]
        public string Id { get; set; }

        /// <summary>
        /// Gets or sets name of the object.
        /// </summary>
        [DataMember(Name = "displayName")]
        public virtual string DisplayName { get; set; }

        /// <summary>
        /// Gets or sets the date/time when the item was created. It is read-only. The setter is for serialization purpose only.
        /// </summary>
        [DataMember(Name = "createdDateTime")]
        [ReadOnly(true)]
        public virtual DateTimeOffset CreatedDateTime { get; set; }
        /// <summary>
        /// Gets or sets odata id.
        /// </summary>
        [NotMapped]
        [DataMember(Name = "odata.id")]
        public Uri OdataId { get; set; }

        /// <summary>
        /// Gets or sets display name of this source.
        /// </summary>
        [DataMember(Name = "displayName")]
        [ReadOnly(true)]
        public override string DisplayName { get; set; }

        /// <summary>
        /// Gets or sets the time this entity was created.
        /// </summary>
        [DataMember(Name = "createdDateTime")]
        [ReadOnly(true)]
        public override DateTimeOffset CreatedDateTime { get; set; }

        /// <summary>
        /// Gets or sets the creator of this entity.
        /// </summary>
        [DataMember(Name = "createdBy")]
        [ReadOnly(true)]
        public IdentitySet CreatedBy { get; set; }

        /// <summary>
        /// Gets or sets the hold status of the dataSource within the case.
        /// </summary>
        [DataMember(Name = "holdStatus")]
        [ReadOnly(true)]
        public DataSourceHoldStatus HoldStatus { get; set; }
    }

    public class SiteSource : DataSource
    {
        /// <summary>
        /// Gets or sets site source.
        /// </summary>
        [DataMember(Name = "site")]
        [Required]
        [Contained]
        [AutoExpand]
        public Site Site { get; set; }
    }

    public class UnifiedGroupSource : DataSource
    {
        /// <summary>
        /// Gets or sets unified group for the data source.
        /// </summary>
        [DataMember(Name = "group")]
        [Required]
        [Contained]
        [AutoExpand]
        public Group Group { get; set; }

        /// <summary>
        /// Gets or sets types of source related to the group. Includes mailbox and site both by default.
        /// </summary>
        [DataMember(Name = "includedSources")]
        public SourceType? IncludedSources { get; set; }
    }

    public class UserSource : DataSource
    {
        /// <summary>
        /// Gets or sets user Source.
        /// </summary>
        [DataMember(Name = "email")]
        [Required]
        public string Email { get; set; }

        /// <summary>
        /// Gets or sets types of source related to the group. Includes mailbox and site both by default.
        /// </summary>
        [DataMember(Name = "includedSources")]
        public SourceType? IncludedSources { get; set; }

        /// <summary>
        /// Gets or sets the web url for site.
        /// </summary>
        [DataMember(Name = "siteWebUrl")]
        public string SiteWebUrl { get; set; }
    }

Expected result

What would happen if there wasn't a bug. Action should return all the DataSOurces

Actual result

Throwing error. Value cannot be null.(Parameter 'structuredType'). Please refer call stack.

Additional detail

Call stack: Value cannot be null. (Parameter 'structuredType') at Microsoft.AspNetCore.OData.Edm.AutoSelectExpandHelper.GetAutoSelectPaths(IEdmModel edmModel, IEdmStructuredType structuredType, IEdmProperty pathProperty, ModelBoundQuerySettings querySettings) at Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption.GetAutoSelectExpandItems(IEdmEntityType baseEntityType, IEdmModel model, IEdmNavigationSource navigationSource, Boolean isAllSelected, ModelBoundQuerySettings modelBoundQuerySettings, Int32 depth, List1& autoSelectItems, List1& autoExpandItems) at Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption.ProcessLevels(ExpandedNavigationSelectItem expandItem, Int32 levelsMaxLiteralExpansionDepth, ModelBoundQuerySettings querySettings, Boolean& levelsEncounteredInExpand, Boolean& isMaxLevelInExpand) at Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption.ProcessLevels(IEnumerable`1 selectItems, Int32 levelsMaxLiteralExpansionDepth, ModelBoundQuerySettings querySettings, Boolean& levelsEncountered, Boolean& isMaxLevel) at Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption.ProcessLevels(SelectExpandClause selectExpandClause, Int32 levelsMaxLiteralExpansionDepth, ModelBoundQuerySettings querySettings, Boolean& levelsEncountered, Boolean& isMaxLevel) at Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption.ProcessLevels() at Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption.get_ProcessedSelectExpandClause() at Microsoft.AspNetCore.OData.Query.ODataQueryOptions.ApplySelectExpand[T](T entity, ODataQuerySettings querySettings) at Microsoft.AspNetCore.OData.Query.ODataQueryOptions.ApplyTo(IQueryable query, ODataQuerySettings querySettings) at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions) at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ExecuteQuery(Object responseValue, IQueryable singleResultCollection, ControllerActionDescriptor actionDescriptor, HttpRequest request) at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.OnActionExecuted(ActionExecutedContext actionExecutedContext, Object responseValue, IQueryable singleResultCollection, ControllerActionDescriptor actionDescriptor, HttpRequest request) at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.OnActionExecuted(ActionExecutedContext actionExecutedContext) at Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute.d6.MoveNext() in //src/Mvc/Mvc.Core/src/Filters/ActionFilterAttribute.cs:line 51 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151 at System.Runtime.CompilerServices.TaskAwaiter.GetResult() in /_/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 107 at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<g__Awaited|100>d.MoveNext() in //src/Mvc/Mvc.Core/src/Infrastructure/ControllerActionInvoker.cs:line 323 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) in //src/Mvc/Mvc.Core/src/Infrastructure/ControllerActionInvoker.cs:line 509 at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) in /_/src/Mvc/Mvc.Core/src/Infrastructure/ControllerActionInvoker.cs:line 275 at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<gAwaited|130>d.MoveNext() in //src/Mvc/Mvc.Core/src/Infrastructure/ControllerActionInvoker.cs:line 487 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151 at System.Runtime.CompilerServices.TaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 107 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<g__Awaited|240>d.MoveNext() in //src/Mvc/Mvc.Core/src/Infrastructure/ResourceInvoker.cs:line 961 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) in //src/Mvc/Mvc.Core/src/Infrastructure/ResourceInvoker.cs:line 1441 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) in /_/src/Mvc/Mvc.Core/src/Infrastructure/ResourceInvoker.cs:line 878 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<gAwaited|190>d.MoveNext() in //src/Mvc/Mvc.Core/src/Infrastructure/ResourceInvoker.cs:line 237 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151 at System.Runtime.CompilerServices.TaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 107 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<gLogged|171>d.MoveNext() in //src/Mvc/Mvc.Core/src/Infrastructure/ResourceInvoker.cs:line 171 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151 at System.Runtime.CompilerServices.TaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 107 at Microsoft.AspNetCore.Routing.EndpointMiddleware.<gAwaitRequestTask|60>d.MoveNext() in //src/Http/Routing/src/EndpointMiddleware.cs:line 79 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151 at System.Runtime.CompilerServices.TaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 107 at Microsoft.Compliance.EDiscovery.GraphService.Middleware.GwsForwardingMiddleware.d3.MoveNext() in E:\src\microservices\eDiscoverySvc\sources\dev\Services\GraphService\src\Service\Middleware\GwsForwardingMiddleware.cs:line 51 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151 at System.Runtime.CompilerServices.TaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 107 at Microsoft.Compliance.EDiscovery.Common.Logging.TracingMiddleware.d2.MoveNext() in E:\src\microservices\eDiscoverySvc\sources\dev\Common\Common\Logging\TracingMiddleware.cs:line 71 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151 at System.Runtime.CompilerServices.TaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 107 at Microsoft.Compliance.EDiscovery.Common.Auth.AuthenticationMiddleware.d12.MoveNext() in E:\src\microservices\eDiscoverySvc\sources\dev\Common\Common\Auth\AuthenticationMiddleware.cs:line 125 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151 at System.Runtime.CompilerServices.TaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 107 at Microsoft.Compliance.EDiscovery.GraphService.Middleware.EgsExceptionMiddleware.d__3.MoveNext() in E:\src\microservices\eDiscoverySvc\sources\dev\Services\GraphService\src\Service\Middleware\EgsExceptionMiddleware.cs:line 44

kapilratra02 commented 2 years ago

@Sreejithpin @xuzhg Can you please have a look at issue and suggest if any workaround ?

xuzhg commented 2 years ago

@kapilratra02 It should be fixed already in 8.0.4. Would you please try the latest version and let me know the result?