Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional Navigations Broken (Nullable object must have a value) #1035

Closed
andy-clymer opened this issue Aug 30, 2023 · 15 comments · May be fixed by #1040
Closed

Optional Navigations Broken (Nullable object must have a value) #1035

andy-clymer opened this issue Aug 30, 2023 · 15 comments · May be fixed by #1040
Assignees
Labels
bug Something isn't working regression

Comments

@andy-clymer
Copy link

Assemblies affected
ASP.NET Core OData 8.2.2
.NET 7
EF Core 7.0.10

Describe the bug
When expanding a navigation property that can be nullable, and the result set returns at least one record that doesn't have a value set for this optional navigation (null), the following error is returned: Nullable object must have a value.

This works in version 8.2.0, but is broken in both the version listed above and 8.2.1.

Reproduce steps

  1. Have a navigation property on your data model that is a related entity that is optional (nullable).
  2. Either configure the property on the EDM entity type to be automatically expanded, or just add the property to your expand query parameter.
  3. Ensure the result set returns at least one record that doesn't have a value set for this optional navigation.

Data Model

public class User
{
    public User(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
    
    public Guid Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Age { get; set; }

    // Foreign Keys
    public Guid? VehicleId { get; set; }
    
    // Navigations
    public Vehicle? PrimaryVehicle { get; set; }
}

EDM (CSDL) Model

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:DataServices>
    <Schema Namespace="ODataSample.Data" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityType Name="User">
        <Key>
          <PropertyRef Name="id" />
        </Key>
        <Property Name="id" Type="Edm.Guid" Nullable="false" />
        <Property Name="firstName" Type="Edm.String" Nullable="false" />
        <Property Name="lastName" Type="Edm.String" Nullable="false" />
        <Property Name="age" Type="Edm.Int32" Nullable="false" />
        <Property Name="vehicleId" Type="Edm.Guid" />
        <NavigationProperty Name="primaryVehicle" Type="ODataSample.Data.Vehicle">
          <ReferentialConstraint Property="vehicleId" ReferencedProperty="id" />
        </NavigationProperty>
      </EntityType>
      <EntityType Name="Vehicle">
        <Key>
          <PropertyRef Name="id" />
        </Key>
        <Property Name="id" Type="Edm.Guid" Nullable="false" />
        <Property Name="make" Type="Edm.String" Nullable="false" />
        <Property Name="model" Type="Edm.String" Nullable="false" />
        <Property Name="color" Type="Edm.String" Nullable="false" />
      </EntityType>
    </Schema>
    <Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityContainer Name="Container">
        <EntitySet Name="Users" EntityType="ODataSample.Data.User">
          <NavigationPropertyBinding Path="primaryVehicle" Target="Vehicles" />
        </EntitySet>
        <EntitySet Name="Vehicles" EntityType="ODataSample.Data.Vehicle" />
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>
public static IEdmModel GetEdmModelV1()
  {
      var builder = new ODataConventionModelBuilder();
      builder.EnableLowerCamelCase();

      // Users
      var userSet = builder.EntitySet<User>("Users");
      var userType = userSet.EntityType;
      userType.HasKey(t => t.Id);
      userType.Property(t => t.FirstName);
      userType.Property(t => t.LastName);
      userType.Property(t => t.Age);
      userType.Property(t => t.VehicleId);
      userType.HasOptional(t => t.PrimaryVehicle);

      // Vehicles
      var vehicleSet = builder.EntitySet<Vehicle>("Vehicles");
      var vehicleType = vehicleSet.EntityType;
      vehicleType.HasKey(t => t.Id);
      vehicleType.Property(t => t.Make);
      vehicleType.Property(t => t.Model);
      vehicleType.Property(t => t.Color);

      return builder.GetEdmModel();
  }

Request/Response
Request Uri:

https://localhost:7012/v1/Users?$expand=primaryVehicle

Response:

Status Code: 500 - Nullable object must have a value.

Expected behavior
Expected behavior is to return a response of the queried records that have the optional navigation set if they contain a value and for records that don't have a value set to also be returned. This would make querying work with optional navigations work like it did in version 8.2.0.

Additional context
System.InvalidOperationException: Nullable object must have a value.
at System.Nullable1.get_Value() at lambda_method18(Closure, QueryContext, DbDataReader, ResultContext, SplitQueryResultCoordinator) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.MoveNextAsync()
at System.Text.Json.Serialization.Converters.IAsyncEnumerableOfTConverter2.OnWriteResume(Utf8JsonWriter writer, TAsyncEnumerable value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.JsonCollectionConverter2.OnTryWrite(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.Serialization.JsonConverter1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.JsonConverter1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.Serialization.JsonConverter`1.WriteCoreAsObject(Utf8JsonWriter writer, Object value, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteCore[TValue](Utf8JsonWriter writer, TValue& value, JsonTypeInfo jsonTypeInfo, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteStreamAsync[TValue](Stream utf8Json, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
at System.Text.Json.JsonSerializer.WriteStreamAsync[TValue](Stream utf8Json, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
at System.Text.Json.JsonSerializer.WriteStreamAsync[TValue](Stream utf8Json, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|28_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

@andy-clymer andy-clymer added the bug Something isn't working label Aug 30, 2023
@xuzhg
Copy link
Member

xuzhg commented Aug 30, 2023

It's a regression coming from #993
The root cause is from https://github.com/OData/AspNetCoreOData/blob/main/src/Microsoft.AspNetCore.OData/Query/Expressions/SelectExpandBinder.cs#L463-L464 in the new method named "RemoveNonStructucalProperties".

There's a StackOverflow question here. I can reproduce it using the sample provided here

From the sample data:
image

You can see User(1) and User(3) have 'null' DataFileRef.

With the #993 changes, the LINQ expression has changed from left to right as below:

image

The exception is thrown from the lines in the "black rectangle of the right picture", since "$$it.FileRefNavigation" is null for User(1) and User(3).

If I change the LINQ expression as (part):

image

, and It works

image

My suggestion:

  1. The method of 'RemoveNonStructucalProperties' is over-coded for the LINQ expression, which makes the LINQ expression complex.
  2. It will be a perf bottleneck if the schema is big (a lot of properties in one type). LINQ expression will be big, and two foreach are time-consuming.
  3. It doesn't take the query setting into consideration.

@goatrodeosoftware
Copy link

I've also produced this bug with optional references and have been unable to solve the issue with marking properties as optional in the OData definition.

@xuzhg
Copy link
Member

xuzhg commented Aug 30, 2023

@goatrodeosoftware @andy-clymer see my previous comments.

@goatrodeosoftware
Copy link

@xuzhg What would I see about your post? I read it and understand and was hoping to show that I experienced it and couldn't get around it with OData configuration.

@xuzhg
Copy link
Member

xuzhg commented Aug 30, 2023

@xuzhg What would I see about your post? I read it and understand and was hoping to show that I experienced it and couldn't get around it with OData configuration.

I can build a nightly for you to try it if you are interested. Just let me know. We hope we can fix it as soon as possible and release the official bit.

xuzhg added a commit that referenced this issue Aug 30, 2023
@xuzhg
Copy link
Member

xuzhg commented Aug 30, 2023

@andy-clymer @goatrodeosoftware can you try the nightly Microsoft.AspNetCore.OData 8.9.0-Nightly202308302217

@goatrodeosoftware
Copy link

goatrodeosoftware commented Aug 30, 2023

@xuzhg I'm sorry, I misunderstood you- I didn't mean that you had to fix something right away to satisfy what I needed, just trying to add info in case it helps. Looks like you've already got it under control. As for me I can just use 8.2.0. I'm happy to try that, but I don't see the package in nuget- does that refer to a branch I'd need to download and reference instead of the nuget package?

@xuzhg
Copy link
Member

xuzhg commented Aug 31, 2023

@xuzhg I'm sorry, I misunderstood you- I didn't mean that you had to fix something right away to satisfy what I needed, just trying to add info in case it helps. Looks like you've already got it under control. As for me I can just use 8.2.0. I'm happy to try that, but I don't see the package in nuget- does that refer to a branch I'd need to download and reference instead of the nuget package?

It doesn't matter. If you want to try the nightly (it's not on Nuget.org, but on Myget.Org), see the guides at https://github.com/OData/aspNetCoreOData/#34-nightly-builds .

@andy-clymer
Copy link
Author

@andy-clymer @goatrodeosoftware can you try the nightly Microsoft.AspNetCore.OData 8.9.0-Nightly202308302217

@xuzhg Thanks for the quick response and action on this issue. I tried the nightly build that you referenced, and now receive a new error: Argument types do not match. The result still returns okay when this property isn't expanded, however the error arises now whenever I request expansion on that property, even if I only filter to return records that have a value set for the optional navigation.

** Stack Trace**
System.ArgumentException: Argument types do not match
at System.Linq.Expressions.Expression.Condition(Expression test, Expression ifTrue, Expression ifFalse)
at Microsoft.AspNetCore.OData.Query.Expressions.SelectExpandBinder.RemoveNonStructucalProperties(QueryBinderContext context, Expression source, IEdmStructuredType structuredType)
at Microsoft.AspNetCore.OData.Query.Expressions.SelectExpandBinder.ProjectElement(QueryBinderContext context, Expression source, SelectExpandClause selectExpandClause, IEdmStructuredType structuredType, IEdmNavigationSource navigationSource)
at Microsoft.AspNetCore.OData.Query.Expressions.SelectExpandBinder.BindSelectExpand(SelectExpandClause selectExpandClause, QueryBinderContext context)
at Microsoft.AspNetCore.OData.Query.Expressions.BinderExtensions.ApplyBind(ISelectExpandBinder binder, IQueryable source, SelectExpandClause selectExpandClause, QueryBinderContext context)
at Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption.ApplyTo(IQueryable queryable, ODataQuerySettings settings)
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.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

@xuzhg
Copy link
Member

xuzhg commented Aug 31, 2023

@andy-clymer @goatrodeosoftware can you try the nightly Microsoft.AspNetCore.OData 8.9.0-Nightly202308302217

@xuzhg Thanks for the quick response and action on this issue. I tried the nightly build that you referenced, and now receive a new error: Argument types do not match. The result still returns okay when this property isn't expanded, however the error arises now whenever I request expansion on that property, even if I only filter to return records that have a value set for the optional navigation.

** Stack Trace** System.ArgumentException: Argument types do not match at System.Linq.Expressions.Expression.Condition(Expression test, Expression ifTrue, Expression ifFalse) at Microsoft.AspNetCore.OData.Query.Expressions.SelectExpandBinder.RemoveNonStructucalProperties(QueryBinderContext context, Expression source, IEdmStructuredType structuredType) at Microsoft.AspNetCore.OData.Query.Expressions.SelectExpandBinder.ProjectElement(QueryBinderContext context, Expression source, SelectExpandClause selectExpandClause, IEdmStructuredType structuredType, IEdmNavigationSource navigationSource) at Microsoft.AspNetCore.OData.Query.Expressions.SelectExpandBinder.BindSelectExpand(SelectExpandClause selectExpandClause, QueryBinderContext context) at Microsoft.AspNetCore.OData.Query.Expressions.BinderExtensions.ApplyBind(ISelectExpandBinder binder, IQueryable source, SelectExpandClause selectExpandClause, QueryBinderContext context) at Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption.ApplyTo(IQueryable queryable, ODataQuerySettings settings) 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.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

I hardcoded the nullable is "int?" So, It seems you have other nullable type?
Anyway, thanks for your trying. We will improve the codes.

@andy-clymer
Copy link
Author

@andy-clymer @goatrodeosoftware can you try the nightly Microsoft.AspNetCore.OData 8.9.0-Nightly202308302217

@xuzhg Thanks for the quick response and action on this issue. I tried the nightly build that you referenced, and now receive a new error: Argument types do not match. The result still returns okay when this property isn't expanded, however the error arises now whenever I request expansion on that property, even if I only filter to return records that have a value set for the optional navigation.
** Stack Trace** System.ArgumentException: Argument types do not match at System.Linq.Expressions.Expression.Condition(Expression test, Expression ifTrue, Expression ifFalse) at Microsoft.AspNetCore.OData.Query.Expressions.SelectExpandBinder.RemoveNonStructucalProperties(QueryBinderContext context, Expression source, IEdmStructuredType structuredType) at Microsoft.AspNetCore.OData.Query.Expressions.SelectExpandBinder.ProjectElement(QueryBinderContext context, Expression source, SelectExpandClause selectExpandClause, IEdmStructuredType structuredType, IEdmNavigationSource navigationSource) at Microsoft.AspNetCore.OData.Query.Expressions.SelectExpandBinder.BindSelectExpand(SelectExpandClause selectExpandClause, QueryBinderContext context) at Microsoft.AspNetCore.OData.Query.Expressions.BinderExtensions.ApplyBind(ISelectExpandBinder binder, IQueryable source, SelectExpandClause selectExpandClause, QueryBinderContext context) at Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption.ApplyTo(IQueryable queryable, ODataQuerySettings settings) 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.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

I hardcoded the nullable is "int?" So, It seems you have other nullable type? Anyway, thanks for your trying. We will improve the codes.

That's correct, we use "Guid?" as our foreign key.

@xuzhg
Copy link
Member

xuzhg commented Sep 6, 2023

@andy-clymer @goatrodeosoftware would you please try the 8.2.3 and let us know any result? Thanks.

@andy-clymer
Copy link
Author

@xuzhg everything is working correctly now. Thank you.

@xuzhg
Copy link
Member

xuzhg commented Sep 6, 2023

@andy-clymer Thanks for your information. Let me close this issue and please file any new issue if you have more questions/concerns.

@xuzhg xuzhg closed this as completed Sep 6, 2023
@goranhrovat
Copy link

goranhrovat commented May 31, 2024

in 8.2.5 is broken again

System.InvalidOperationException: Nullable object must have a value.
at lambda_method88(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteResourceSetAsync(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObjectInlineAsync(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObjectAsync(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
at Microsoft.AspNetCore.OData.Formatter.ODataOutputFormatterHelper.WriteToStreamAsync(Type type, Object value, IEdmModel model, ODataVersion version, Uri baseAddress, MediaTypeHeaderValue contentType, HttpRequest request, IHeaderDictionary requestHeaders, IODataSerializerProvider serializerProvider)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working regression
Projects
None yet
6 participants