Breeze / breeze.server.net

Breeze support for .NET servers
MIT License
76 stars 63 forks source link

Error when using "in" on an array of Enum strings #199

Open russelg opened 4 months ago

russelg commented 4 months ago

I get the following error when I try to use "in" with an array of Enum strings:

The value passed in must be an enum base or an underlying type for an enum, such as an Int32. (Parameter 'value')
   at System.Enum.ToObject(Type enumType, Object value)
   at Breeze.Core.BinaryPredicate.Validate(Type entityType)
   at Breeze.Core.AndOrPredicate.<>c__DisplayClass5_0.<Validate>b__0(BasePredicate p)
   at System.Collections.Generic.List`1.ForEach(Action`1 action)
   at Breeze.Core.AndOrPredicate.Validate(Type entityType)
   at Breeze.Core.EntityQuery.Validate(Type entityType)
   at Breeze.AspNetCore.BreezeQueryFilterAttribute.OnActionExecuted(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>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.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

Query:

{
    "toType": "OutstandingSurveyResponse",
    "where": {
        "Survey.Status": "Started",
        "Survey.SurveyType": {
            "in": [
                "EmployeeEngagement",
                "TeamAssessment",
                "ResilientBusinessAssessment"
            ]
        }
    }
}

Entities:

public enum SurveyStatus
{
    NotStarted = 0,
    Started = 1,
    Ended = 2,
}

public enum SurveyType
{
    EmployeeEngagement = 0,
    TeamAssessment = 1,
    ResilientBusinessAssessment = 2,
    OrganisationDiagnostic = 3,
}

public class Survey
{
    public int SurveyId { get; set; }
    public SurveyStatus Status { get; set; }
    public SurveyType SurveyType { get; set; }

    public virtual ICollection<OutstandingSurveyResponse> OutstandingSurveyResponses { get; set; }
}

public class OutstandingSurveyResponse
{
    public int OutstandingSurveyResponseId { get; set; }
    public int SurveyId { get; set; }

    public virtual Survey Survey { get; set; }
}

Ran into this while porting a codebase from .NET Framework 4.8/EF6/ASP.NET to .NET 8.0/EF Core/ASP.NET Core. The old codebase uses string Enums, and we don't want to particularly move away from them at this point (it would cause a tonne of changes in our frontend code which we want to avoid).

I have set BreezeConfig.Instance.UseIntEnums = false; and called UpdateWithDefaults with false for useIntEnums.

steveschmitt commented 4 months ago

Hmm. I wonder if I broke this when I added support for int enums, or if we broke it when we moved to .NET Core a long time ago.

Thanks for finding this.