예제 #1
0
        private Expression GetPredicateBody(HttpRequestMessage request, ParameterExpression param)
        {
            Expression workingExpr = null;

            var type       = param.Type;
            var queryPairs = request.GetQueryNameValuePairs();

            foreach (var queryPair in queryPairs)
            {
                if (String.IsNullOrWhiteSpace(queryPair.Key))
                {
                    continue;
                }

                if (!queryPair.Key.StartsWith("filter."))
                {
                    continue;
                }

                if (queryPair.Key.StartsWith("filter.calculated."))
                {
                    continue;
                }

                var filterField = queryPair.Key.Substring(7); // Skip "filter."

                IResourceTypeRegistration registration;
                try
                {
                    registration = _resourceTypeRegistry.GetRegistrationForType(type);
                }
                catch (TypeRegistrationNotFoundException)
                {
                    throw JsonApiException.CreateForBadRequest("No registration exists for the specified type");
                }

                var expr = GetPredicate(filterField, registration, param, queryPair.Value);
                workingExpr = workingExpr == null ? expr : Expression.AndAlso(workingExpr, expr);
            }

            return(workingExpr ?? Expression.Constant(true)); // No filters, so return everything
        }
예제 #2
0
        private Expression GetPredicate(string filterField, IResourceTypeRegistration registration, ParameterExpression param, string queryValue)
        {
            if (filterField == "id")
            {
                return(GetPredicateBodyForProperty(registration.IdProperty, queryValue, param));
            }

            var resourceTypeField = registration.GetFieldByName(filterField);

            if (resourceTypeField == null)
            {
                throw JsonApiException.CreateForBadRequest(
                          string.Format("No attribute {0} exists on the specified type.", filterField));
            }

            if (string.IsNullOrWhiteSpace(queryValue))
            {
                queryValue = null;
            }

            // See if it is a field property
            var fieldModelProperty = resourceTypeField as ResourceTypeAttribute;

            if (fieldModelProperty != null)
            {
                return(GetPredicateBodyForField(fieldModelProperty, queryValue, param));
            }

            // See if it is a relationship property
            var relationshipModelProperty = resourceTypeField as ResourceTypeRelationship;

            if (relationshipModelProperty != null)
            {
                return(GetPredicateBodyForRelationship(relationshipModelProperty, queryValue, param));
            }

            throw JsonApiException.CreateForBadRequest(
                      string.Format("The attribute {0} is unsupported for filtering.", filterField));
        }
예제 #3
0
        private Expression GetPredicateBodyForRelationship(ResourceTypeRelationship resourceTypeProperty, string queryValue, ParameterExpression param)
        {
            var          relatedType = resourceTypeProperty.RelatedType;
            PropertyInfo relatedIdProperty;

            try
            {
                var registration = _resourceTypeRegistry.GetRegistrationForType(relatedType);
                relatedIdProperty = registration.IdProperty;
            }
            catch (TypeRegistrationNotFoundException)
            {
                throw JsonApiException.CreateForBadRequest("No registration exists for the specified type");
            }

            var prop = resourceTypeProperty.Property;

            if (resourceTypeProperty.IsToMany)
            {
                var propertyExpr = Expression.Property(param, prop);

                if (string.IsNullOrWhiteSpace(queryValue))
                {
                    var leftExpr = Expression.Equal(propertyExpr, Expression.Constant(null));

                    var asQueryableCallExpr = Expression.Call(
                        typeof(Queryable),
                        "AsQueryable",
                        new[] { relatedType },
                        propertyExpr);
                    var anyCallExpr = Expression.Call(
                        typeof(Queryable),
                        "Any",
                        new[] { relatedType },
                        asQueryableCallExpr);
                    var rightExpr = Expression.Not(anyCallExpr);

                    return(Expression.OrElse(leftExpr, rightExpr));
                }
                else
                {
                    var leftExpr = Expression.NotEqual(propertyExpr, Expression.Constant(null));

                    var idValue  = queryValue.Trim();
                    var idExpr   = Expression.Constant(idValue);
                    var anyParam = Expression.Parameter(relatedType);
                    var relatedIdPropertyExpr         = Expression.Property(anyParam, relatedIdProperty);
                    var relatedIdPropertyEqualsIdExpr = Expression.Equal(relatedIdPropertyExpr, idExpr);
                    var anyPredicateExpr    = Expression.Lambda(relatedIdPropertyEqualsIdExpr, anyParam);
                    var asQueryableCallExpr = Expression.Call(
                        typeof(Queryable),
                        "AsQueryable",
                        new[] { relatedType },
                        propertyExpr);
                    var rightExpr = Expression.Call(
                        typeof(Queryable),
                        "Any",
                        new[] { relatedType },
                        asQueryableCallExpr,
                        anyPredicateExpr);

                    return(Expression.AndAlso(leftExpr, rightExpr));
                }
            }
            else
            {
                var propertyExpr = Expression.Property(param, prop);

                if (string.IsNullOrWhiteSpace(queryValue))
                {
                    return(Expression.Equal(propertyExpr, Expression.Constant(null)));
                }

                var leftExpr = Expression.NotEqual(propertyExpr, Expression.Constant(null));

                var idValue = queryValue.Trim();
                var idExpr  = Expression.Constant(idValue);
                var relatedIdPropertyExpr = Expression.Property(propertyExpr, relatedIdProperty);
                var rightExpr             = Expression.Equal(relatedIdPropertyExpr, idExpr);

                return(Expression.AndAlso(leftExpr, rightExpr));
            }
        }