enisn / AutoFilterer

AutoFilterer is a mini filtering framework library for dotnet. The main purpose of the library is to generate LINQ expressions for Entities over DTOs automatically. The first aim is to be compatible with Open API 3.0 Specifications
MIT License
458 stars 37 forks source link

Range<DateTime> System.InvalidOperationException #59

Open gpproton opened 1 year ago

gpproton commented 1 year ago

I have a sample Filter below which i'm trying to use a date range filter with in asp.net core 7, i'm not that this might be limitation of asp.net minimal API, if there's a solution any suggestion will be appreciated.

Filter sample

public class ClaimFilter : GenericFilter {
    [CompareTo("Description", "Notes", CombineWith = CombineType.And)]
    [StringFilterOptions(StringFilterOption.Contains)]
    public string? Search { get; set; }

    public ClaimStatus[]? Status { get; set; }

    public Range<DateTime> CreatedAt { get; set; }

    // Current work around
    // [CompareTo("CreatedAt")]
    // [OperatorComparison(OperatorType.GreaterThanOrEqual)]
    // public DateTime? StartDate { get; set; }
    //
    // [CompareTo("CreatedAt")]
    // [OperatorComparison(OperatorType.LessThanOrEqual)]
    // public DateTime? EndDate { get; set; }
}

Minimal API sample

group.MapGet("/", async (ClaimService sv, [AsParameters] ClaimFilter filter) =>
                await sv.GetAllAsync(filter))
            .WithName($"GetAll{name}")
            .WithOpenApi();

Error message

An unhandled exception has occurred while executing the request.
      System.InvalidOperationException: Body was inferred but the method does not allow inferred body parameters.
      Below is the list of parameters that we found:

      Parameter           | Source
      ---------------------------------------------------------------------------------
      sv                  | Services (Inferred)
      Search              | Query String (Inferred)
      Status              | Query String (Inferred)
      StartDate           | Query String (Inferred)
      EndDate             | Query String (Inferred)
      CreatedAt           | Body (Inferred)
      Page                | Query String (Inferred)
      Sort                | Query String (Inferred)
      PerPage             | Query String (Inferred)
      SortBy              | Query String (Inferred)
      CombineWith         | Query String (Inferred)
      filter              | As Parameter (Attribute)

      Did you mean to register the "Body (Inferred)" parameter(s) as a Service or apply the [FromServices] or [FromBody] attribute?
enisn commented 1 year ago

According to the error message, you can try adding [FromQuery] attribute but I don't think it'll work.

How do you send the request? Can you share?

The parameter should contain dot like ?CreatedAt.Min=01.01.2023. But dot is used to initialize complex types and bind properties of that types.

Since Range<T> is a complex type and it seems like the minimal API model binder doesn't support it.

I have a sample Filter below which i'm trying to use a date range filter with in asp.net core 7, i'm not that this might be limitation of asp.net minimal API, if there's a solution any suggestion will be appreciated.

Filter sample

public class ClaimFilter : GenericFilter {
    [CompareTo("Description", "Notes", CombineWith = CombineType.And)]
    [StringFilterOptions(StringFilterOption.Contains)]
    public string? Search { get; set; }

    public ClaimStatus[]? Status { get; set; }

    public Range<DateTime> CreatedAt { get; set; }

    // Current work around
    // [CompareTo("CreatedAt")]
    // [OperatorComparison(OperatorType.GreaterThanOrEqual)]
    // public DateTime? StartDate { get; set; }
    //
    // [CompareTo("CreatedAt")]
    // [OperatorComparison(OperatorType.LessThanOrEqual)]
    // public DateTime? EndDate { get; set; }
}

Your current workaround seems good at the moment. Sending those parameters separated works well.