public IEnumerable <ValidationResult> Validate(ValidationContext validationContext)
        {
            var result = new List <ValidationResult>();

            if (string.IsNullOrWhiteSpace(FilterExpr))
            {
                return(result);
            }

            var reader = new FilterReader(FilterReader.Utf8Encoding.GetBytes(FilterExpr));

            if (FilterReaderHelper.TryRead(ref reader, FilterExpr, TargetModelPropertyInfos, out var tokens, out var error))
            {
                Tokens = tokens;

                var parser = new FilterParser(tokens, TargetModelPropertyInfos);
                try
                {
                    var node = parser.Parse();
                    Node = node;
                }
                catch (FilterException e)
                {
                    result.Add(new ValidationResult(e.Message, new[] { "$filter" }));
                }

                Validate(Node, result);
            }
Example #2
0
        public static bool TryRead(ref FilterReader reader, string filterExpr, IList <PropertyInfo> propertyInfos, out IList <Token> tokens, out string error)
        {
            var position = 0;
            var retVal   = true;

            tokens = new List <Token>();
            error  = null;

            try
            {
                while (true)
                {
                    if (!reader.Read())
                    {
                        break;
                    }

                    var val = FilterReader.Utf8Encoding.GetString(reader.ValueSpan);
                    var i   = filterExpr.IndexOf(val, position, StringComparison.Ordinal) + 1;
                    position += val.Length;
                    switch (reader.TokenType)
                    {
                    case FilterTokenType.PropertyName:
                    {
                        var propertyName = val.StartsWith((char)FilterConstants.At) ? val.Substring(1) : val;
                        if (!propertyInfos.Any(x => x.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase)))
                        {
                            throw new FilterException($"不存在的属性: {propertyName}。");
                        }

                        tokens.Add(new Token(FilterTokenType.PropertyName, propertyName, i));
                        break;
                    }

                    case FilterTokenType.StartGrouping:
                    case FilterTokenType.EndGrouping:
                    case FilterTokenType.UnaryLogicalOperator:
                    case FilterTokenType.BinaryLogicalOperator:
                    case FilterTokenType.RelationalOperator:
                    case FilterTokenType.Number:
                    case FilterTokenType.True:
                    case FilterTokenType.False:
                    case FilterTokenType.Null:
                        tokens.Add(new Token(reader.TokenType, val, i));
                        break;

                    case FilterTokenType.String:
                    {
                        var s = val.Substring(1, val.Length - 2);
                        tokens.Add(new Token(reader.TokenType, s, i));
                        break;
                    }

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }
            catch (FormatException e)
            {
                retVal = false;
                error  = e.Message;
            }

            return(retVal);
        }