Preview
Name Surname Marital status Age Employed
Joe Crosswave Married 32 False
Merry Lisel Widowed 41
Henry Crux Single 29 True
Cody Jurut 49 False
Simon Scranton Single 34
Leena Laurent Divorced 19 False
Ode Cosmides Married 53 True
Diandra Mizner Single 20 False
Pete Cassel Married 23 False
Nicky Tremblay Married 32 True
Mary Cassel Married 24 True
Startup

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvcGrid(filters =>
        filters.Register(typeof(Int32), "contains", typeof(NumberContainsFilter)));
}

Filter

public class NumberContainsFilter : AGridFilter
{
    public override Expression? Apply(Expression expression)
    {
        if (Values.Length == 0 || Values.Any(String.IsNullOrEmpty))
            return null;

        return base.Apply(expression);
    }

    protected override Expression? Apply(Expression expression, String? value)
    {
        Expression valueExpression = Expression.Constant(value?.ToUpper());
        MethodInfo toStringMethod = typeof(Int32).GetMethod(nameof(Int32.ToString), new Type[0])!;
        MethodInfo containsMethod = typeof(String).GetMethod(nameof(String.Contains), new[] { typeof(String) })!;

        Expression toString = Expression.Call(expression, toStringMethod);

        // (x) => x.ToString().Contains(value)
        return Expression.Call(toString, containsMethod, valueExpression);
    }
}

Javascript

class ExtendedNumberFilter extends MvcGridNumberFilter {
    constructor (column) {
        super(column);

        this.methods.unshift("contains");
    }
}

new MvcGrid(document.querySelector(".mvc-grid"), {
    filters: {
        "number": ExtendedNumberFilter
    }
});

MvcGrid.lang.number.contains = "Contains";