Skip to content

How to implement a custom filter #1277

Closed
@max-maurice

Description

@max-maurice

SUMMARY

I'm trying to allow custom filter strings like this:

http://localhost/ressource?filter=lessThan(createdAt,'-00:10:00')

which would mean to return all ressources where the createdAt datetime value is less than 10 minutes in the past.

In JADNC before 5.2.0 this worked when using a QueryRewriter like my TimespanExpressionRewriter below. Since version 5.2.0, JADNC throws an exception: "Failed to convert '-00:10:00' of type 'String' to type 'DateTime'."

I suppose the TimespanExpressionRewriter is not the right way to go. Hence my question: How do we implement a custom filter like that?

I've already dug around in the JADNC sources without success.

DETAILS

My TimespanExpressionRewriter class overrides VisitComparison() and replaces an expression when the right value looks like -00:00:00. It returns the rewritten expression like this:

  • Input: lessThan(updatedAt,'-1.06:00')
  • Output: and(greaterThan(updatedAt,'2000-06-30T10:00:00+02:00'),lessOrEqual(updatedAt,'2000-07-01T16:00:00+02:00'))

In JADNC <5.2.0 this worked, when adding the expression rewriting in a ResourceDefinition like this:

public override FilterExpression? OnApplyFilter(FilterExpression? existingFilter)
{
    if (existingFilter != null)
    {
        // Timespan expression
        // Example:
        // http://localhost/ressources?filter=lessThan(createdAt%2C'-0.00%3A50%3A00')

        existingFilter = new TimespanExpressionRewriter().Visit(existingFilter, null) as FilterExpression;
    }

    return existingFilter;
}

TimespanExpressionRewriter:

public class TimespanExpressionRewriter : QueryExpressionRewriter<object?>
{
    public override QueryExpression? VisitComparison(ComparisonExpression expression, object? argument)
    {
        // TryCreate() replaces "expression" if it contains a relative timespan
        if (TimespanExpressionFactory.TryCreate(expression, () => DateTime.UtcNow, out var expr))
        {
            return expr;
        }

        return base.VisitComparison(expression, argument);
    }

    public override QueryExpression? Visit(QueryExpression expression, object argument)
    {
        return base.Visit(expression, argument);
    }
}

STEPS TO REPRODUCE

VERSIONS USED

  • JsonApiDotNetCore version: 5.2.0
  • ASP.NET Core version: 7
  • Entity Framework Core version: 7.0.5
  • Database provider: MSSQL

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions