ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
5.16k stars 736 forks source link

UseProjections in Combination with BindMember throws Exception #5054

Open BickelLukas opened 2 years ago

BickelLukas commented 2 years ago

Is there an existing issue for this?

Describe the bug

Model

class Item
{
    public string Subject { get; set; }
    public string User { get; set; }
}

class User 
{
    public string Username { get; set; }
}

Query

class Query 
{
    [UseOffsetPaging]
    [UseProjection]
    public IQueryable<Item> GetItems(IAsyncDocumentSession session)
    {
        return session.Query<Item>();
    }
}

Type Extension

[ExtendObjectType(typeof(Item))]
public class ItemTypeExtension
{
    [BindMember(nameof(Item.User))]
    public async Task<User> GetUser([Parent] Item item,  IAsyncDocumentSession session)
        => await session.LoadAsync<User>(item.User);
}

When querying for items and the projection visitor throws an exception when the user is queried: The follwing works

query {
  items {
    subject
  }
}

This throws the following exception Property 'System.String Username' is not defined for type 'System.String' (Parameter 'property')

query {
  items {
    subject
    user {
      username
    }
  }
}

Steps to reproduce

https://github.com/glen-84/hc-5054 (.NET 8, HC 14.0.0-rc.1)

  1. Use the above code and execute the query

Relevant log output

at System.Linq.Expressions.Expression.Property(Expression expression, PropertyInfo property)
   at HotChocolate.Data.Projections.Expressions.Handlers.QueryableProjectionScalarHandler.TryHandleLeave(QueryableProjectionContext context, ISelection selection, ISelectionVisitorAction& action)
   at HotChocolate.Data.Projections.ProjectionVisitor`1.Leave(ISelection selection, TContext context)
   at HotChocolate.Data.Projections.SelectionVisitor`1.Visit(ISelection selection, TContext context)
   at HotChocolate.Data.Projections.ProjectionVisitor`1.Visit(ISelection selection, TContext context)
   at HotChocolate.Data.Projections.SelectionVisitor`1.VisitObjectType(IOutputField field, ObjectType objectType, SelectionSetNode selectionSet, TContext context)
   at HotChocolate.Data.Projections.Expressions.QueryableProjectionVisitor.VisitObjectType(IOutputField field, ObjectType objectType, SelectionSetNode selectionSet, QueryableProjectionContext context)
   at HotChocolate.Data.Projections.SelectionVisitor`1.VisitChildren(IOutputField field, TContext context)
   at HotChocolate.Data.Projections.SelectionVisitor`1.Visit(IOutputField field, TContext context)
   at HotChocolate.Data.Projections.ProjectionVisitor`1.Visit(IOutputField field, TContext context)
   at HotChocolate.Data.Projections.SelectionVisitor`1.VisitChildren(ISelection selection, TContext context)
   at HotChocolate.Data.Projections.SelectionVisitor`1.Visit(ISelection selection, TContext context)
   at HotChocolate.Data.Projections.ProjectionVisitor`1.Visit(ISelection selection, TContext context)
   at HotChocolate.Data.Projections.SelectionVisitor`1.VisitObjectType(IOutputField field, ObjectType objectType, SelectionSetNode selectionSet, TContext context)
   at HotChocolate.Data.Projections.Expressions.QueryableProjectionVisitor.VisitObjectType(IOutputField field, ObjectType objectType, SelectionSetNode selectionSet, QueryableProjectionContext context)
   at HotChocolate.Data.Projections.SelectionVisitor`1.VisitChildren(IOutputField field, TContext context)
   at HotChocolate.Data.Projections.SelectionVisitor`1.Visit(IOutputField field, TContext context)
   at HotChocolate.Data.Projections.ProjectionVisitor`1.Visit(IOutputField field, TContext context)
   at HotChocolate.Data.Projections.ProjectionVisitor`1.Visit(TContext context)
   at HotChocolate.Data.Projections.Expressions.QueryableProjectionProvider.<>c__5`1.<CreateApplicatorAsync>b__5_0(IResolverContext context, Object input)
   at HotChocolate.Data.Projections.Expressions.QueryableProjectionProvider.<>c__DisplayClass4_0`1.<<CreateExecutor>g__ExecuteAsync|1>d.MoveNext()
--- End of stack trace from previous location ---
   at HotChocolate.Types.Pagination.PagingMiddleware.InvokeAsync(IMiddlewareContext context)
   at HotChocolate.Utilities.MiddlewareCompiler`1.ExpressionHelper.AwaitTaskHelper(Task task)
   at HotChocolate.AspNetCore.Authorization.AuthorizeMiddleware.InvokeAsync(IDirectiveContext context)
   at HotChocolate.Utilities.MiddlewareCompiler`1.ExpressionHelper.AwaitTaskHelper(Task task)
   at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)
   at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)

Additional Context?

After some investigation I found out the Problem is in the ProjectionVisitor. It is trying to assign a User object to the User Property of the Item which is a string.

Product

Hot Chocolate

Version

12.7.0 and also 13.0.0-preview.19

BickelLukas commented 2 years ago

bump

rkotenko commented 1 year ago

I am trying to use this exact scenario and have encountered the same issue. I would like to see a fix as well.

rkotenko commented 1 year ago

Is there any plan to deal with this? It becoming a big issue for us as we need to rename many model fields.

brianbarenbaum commented 1 year ago

Bump. Any update on this? Thanks!