Esempio n. 1
0
        private Uri CreateEntryContextUri(string selectClause, string expandClause)
        {
            SelectExpandClause selectExpandClause = new ODataQueryOptionParser(edmModel, this.cityType, this.citySet, new Dictionary <string, string> {
                { "$expand", expandClause }, { "$select", selectClause }
            }).ParseSelectAndExpand();
            ODataResourceTypeContext typeContext = ODataResourceTypeContext.Create(/*serializationInfo*/ null, this.citySet, this.cityType, this.cityType, true);
            ODataContextUrlInfo      info        = ODataContextUrlInfo.Create(typeContext, true, new ODataUri()
            {
                SelectAndExpand = selectExpandClause
            });
            Uri contextUrl = this.responseContextUriBuilder.BuildContextUri(ODataPayloadKind.ResourceSet, info);

            return(contextUrl);
        }
Esempio n. 2
0
        private Uri CreateFeedContextUri(string applyClauseString)
        {
            ApplyClause applyClause = new ODataQueryOptionParser(edmModel, this.cityType, this.citySet, new Dictionary <string, string> {
                { "$apply", applyClauseString }
            }).ParseApply();
            ODataResourceTypeContext typeContext = ODataResourceTypeContext.Create(/*serializationInfo*/ null, this.citySet, this.cityType, this.cityType, true);
            ODataContextUrlInfo      info        = ODataContextUrlInfo.Create(typeContext, false, new ODataUri()
            {
                Apply = applyClause
            });
            Uri contextUrl = this.responseContextUriBuilder.BuildContextUri(ODataPayloadKind.ResourceSet, info);

            return(contextUrl);
        }
Esempio n. 3
0
 /// <summary>
 /// Create a ApplyFilterClause from a parse transformation query
 /// </summary>
 /// <param name="apply"></param>
 /// <param name="query"></param>
 /// <param name="oDataUriParserConfiguration"></param>
 /// <param name="edmType"></param>
 /// <param name="edmNavigationSource"></param>
 /// <returns></returns>
 private static ApplyFilterClause ParseFilter(ApplyClause apply, string query, ODataUriParserConfiguration oDataUriParserConfiguration, IEdmType edmType, IEdmNavigationSource edmNavigationSource)
 {
     query = IsolateQuery(query, UriQueryConstants.FilterTransformation);
     return(new ApplyFilterClause()
     {
         Apply = apply,
         Filter = ODataQueryOptionParser.ParseFilterImplementation(
             query,
             oDataUriParserConfiguration,
             edmType,
             edmNavigationSource),
         RawQueryString = query
     });
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataQueryOptions"/> class based on the incoming request and some metadata information from
        /// the <see cref="ODataQueryContext"/>.
        /// </summary>
        /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information.</param>
        private void Initialize(ODataQueryContext context)
        {
            Contract.Assert(context != null);

            ODataUriResolver uriResolver = null;

            if (context.RequestContainer != null)
            {
                uriResolver = context.RequestContainer.GetService <ODataUriResolver>();
            }

            if (uriResolver != null)
            {
                _enableNoDollarSignQueryOptions = uriResolver.EnableNoDollarQueryOptions;
            }
            else
            {
                // Use the global setting
                _enableNoDollarSignQueryOptions = context.Request.IsNoDollarQueryEnable();
            }

            // Parse the query from request Uri, including only keys which are OData query parameters or parameter alias
            // OData query parameters are normalized with the $-sign prefixes when the
            // <code>EnableNoDollarSignPrefixSystemQueryOption</code> option is used.
            RawValues = new ODataRawQueryOptions();
            IDictionary <string, string> normalizedQueryParameters = GetODataQueryParameters();

            _queryOptionParser = new ODataQueryOptionParser(
                context.Model,
                context.ElementType,
                context.NavigationSource,
                normalizedQueryParameters);

            if (uriResolver != null)
            {
                _queryOptionParser.Resolver = uriResolver;
            }
            else
            {
                // By default, let's enable the property name case-insensitive
                _queryOptionParser.Resolver = new ODataUriResolver {
                    EnableCaseInsensitive = true
                };
            }

            BuildQueryOptions(normalizedQueryParameters);

            Validator = ODataQueryValidator.GetODataQueryValidator(context);
        }
Esempio n. 5
0
        public void CopyConstructorShouldCopyAll()
        {
            this.settings.MetadataSelector = new TestMetadataSelector()
            {
                PropertyToOmit = "TestProperty"
            };
            this.settings.SetContentType("application/json,application/atom+xml", "iso-8859-5, unicode-1-1;q=0.8");
            this.settings.SetServiceDocumentUri(new Uri("http://example.com"));
            this.settings.ArrayPool = new TestCharArrayPool(5);
            this.settings.EnableMessageStreamDisposal = false;
            this.settings.EnableCharactersCheck       = true;

            var edmModel         = new EdmModel();
            var defaultContainer = new EdmEntityContainer("TestModel", "DefaultContainer");

            edmModel.AddElement(defaultContainer);
            var cityType       = new EdmEntityType("TestModel", "City");
            var cityIdProperty = cityType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(/*isNullable*/ false));

            cityType.AddKeys(cityIdProperty);
            cityType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(/*isNullable*/ false));
            cityType.AddStructuralProperty("Size", EdmCoreModel.Instance.GetInt32(/*isNullable*/ false));
            edmModel.AddElement(cityType);
            var citySet = defaultContainer.AddEntitySet("Cities", cityType);

            var result = new ODataQueryOptionParser(edmModel, cityType, citySet, new Dictionary <string, string> {
                { "$expand", "" }, { "$select", "Id,*" }
            }).ParseSelectAndExpand();

            this.settings.ODataUri = new ODataUri()
            {
                ServiceRoot     = new Uri("http://test.org"),
                SelectAndExpand = result,
                Path            = new ODataUriParser(edmModel, new Uri("http://test.org"), new Uri("http://test.org/Cities(1)/Name")).ParsePath()
            };

            this.settings.LibraryCompatibility = ODataLibraryCompatibility.Version6;
            this.settings.Version = ODataVersion.V4;

            Func <string, bool> filter = name => true;

            this.settings.ShouldIncludeAnnotation = filter;

            var newSetting = this.settings.Clone();

            var differences = ValidationHelper.GetDifferences <ODataMessageWriterSettings>(this.settings, newSetting);

            Assert.True(differences.Count == 0, String.Join(",", differences));
        }
Esempio n. 6
0
        private static void TestCaseInsensitive()
        {
            Console.WriteLine("TestCaseInsensitive");
            var parser = new ODataUriParser(
                extModel.Model,
                ServiceRoot,
                new Uri("http://demo/odata.svc/People(1)/Pets/TestNS.Fish?$orderby=Color"));

            var path   = parser.ParsePath();
            var clause = parser.ParseOrderBy();

            Console.WriteLine(path.ToLogString());
            Console.WriteLine(clause.Expression.ToLogString());

            var parser2 = new ODataUriParser(
                extModel.Model,
                ServiceRoot,
                new Uri("http://demo/odata.svc/people(1)/pets/testns.fish?$ORDERBY=color"))
            {
                Resolver = new ODataUriResolver {
                    EnableCaseInsensitive = true
                }
            };

            // Identical to path and clause
            var path2   = parser2.ParsePath();
            var clause2 = parser2.ParseOrderBy();

            Console.WriteLine(path2.ToLogString());
            Console.WriteLine(clause2.Expression.ToLogString());

            // Query option parser also supports custom resolver
            var parser3 = new ODataQueryOptionParser(
                extModel.Model,
                extModel.Fish,
                extModel.PetSet,
                new Dictionary <string, string>
            {
                { "$orderby", "color" }
            })
            {
                Resolver = new ODataUriResolver {
                    EnableCaseInsensitive = true
                }
            };
            var clause3 = parser3.ParseOrderBy();

            Console.WriteLine(clause3.Expression.ToLogString());
        }
        private QueryNode TranslateFilterExpression(string filter)
        {
            var parser = new ODataQueryOptionParser(_model, _customerEntityType, _customersEntitySet,
                                                    new Dictionary <string, string> {
                { "$filter", filter }
            });
            FilterClause filterClause = parser.ParseFilter();
            var          translator   = new ParameterAliasNodeTranslator(
                new Dictionary <string, SingleValueNode> {
                { "@p", _parameterAliasMappedNode }
            });
            QueryNode translatedNode = filterClause.Expression.Accept(translator);

            return(translatedNode);
        }
Esempio n. 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ApplyQueryOption"/> class.
        /// </summary>
        /// <param name="context">The OData query context.</param>
        /// <param name="queryOptionParser">The OData parser.</param>
        public ApplyQueryOption(ODataQueryContext context, ODataQueryOptionParser queryOptionParser)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            if (queryOptionParser == null)
            {
                throw Error.ArgumentNull("queryOptionParser");
            }

            this.Context            = context;
            this._queryOptionParser = queryOptionParser;
        }
Esempio n. 9
0
        private void ParseAndExtract(string expandClauseText = null, string selectClauseText = null, string expectedExpandClauseFromOM = null, string expectedSelectClauseFromOM = null)
        {
            foreach (ODataVersion version in new ODataVersion[] { ODataVersion.V4, ODataVersion.V401 })
            {
                var expandClause = new ODataQueryOptionParser(this.model, this.baseType, this.entitySet, new Dictionary <string, string> {
                    { "$expand", expandClauseText }, { "$select", selectClauseText }
                }).ParseSelectAndExpand();

                // Verify that the extension method gets the same result as the path extractor.
                string selectTextFromOM, expandTextFromOM;
                expandClause.GetSelectExpandPaths(version, out selectTextFromOM, out expandTextFromOM);
                selectTextFromOM.Should().Be(expectedSelectClauseFromOM ?? (selectClauseText ?? string.Empty));
                expandTextFromOM.Should().Be(expectedExpandClauseFromOM ?? (expandClauseText ?? string.Empty));
            }
        }
Esempio n. 10
0
        public void DuplicatedSelectPathInOneDollarSelectThrows(string select, string error)
        {
            // Arrange
            ODataQueryOptionParser parser = new ODataQueryOptionParser(_model.Model, _model.Customer, _model.Customers,
                                                                       new Dictionary <string, string> {
                { "$select", select }
            });

            // Act
            Action test = () => parser.ParseSelectAndExpand();

            // Assert
            ExceptionAssert.Throws <ODataException>(test,
                                                    String.Format("Found mutliple select terms with same select path '{0}' at one $select, please combine them together.", error));
        }
Esempio n. 11
0
        public void ApplyTo_Returns_Correct_Queryable(string filter, List <Dictionary <string, object> > aggregation)
        {
            // Arrange
            var model = new ODataModelBuilder()
                        .Add_Order_EntityType()
                        .Add_Customer_EntityType_With_Address()
                        .Add_CustomerOrders_Relationship()
                        .Add_Customer_EntityType_With_CollectionProperties()
                        .Add_Customers_EntitySet()
                        .GetEdmModel();
            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockContainer()
            };
            var queryOptionParser = new ODataQueryOptionParser(
                context.Model,
                context.ElementType,
                context.NavigationSource,
                new Dictionary <string, string> {
                { "$apply", filter }
            });
            var applyOption = new ApplyQueryOption(filter, context, queryOptionParser);
            IEnumerable <Customer> customers = CustomerApplyTestData;

            // Act
            IQueryable queryable = applyOption.ApplyTo(customers.AsQueryable(), new ODataQuerySettings {
                HandleNullPropagation = HandleNullPropagationOption.True
            });

            // Assert
            Assert.NotNull(queryable);
            var actualCustomers = Assert.IsAssignableFrom <IEnumerable <DynamicTypeWrapper> >(queryable).ToList();

            Assert.Equal(aggregation.Count(), actualCustomers.Count());

            var aggEnum = actualCustomers.GetEnumerator();

            foreach (var expected in aggregation)
            {
                aggEnum.MoveNext();
                var agg = aggEnum.Current;
                foreach (var key in expected.Keys)
                {
                    object value = GetValue(agg, key);
                    Assert.Equal(expected[key], value);
                }
            }
        }
Esempio n. 12
0
        private static QueryClause CreateQueryClause(string query, IEdmModel model, Type type)
        {
            IEdmEntityType entityType = model.SchemaElements.OfType <IEdmEntityType>().Single(t => t.Name == type.Name);

            Assert.NotNull(entityType); // Guard

            IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");

            Assert.NotNull(entitySet); // Guard

            string[] queryItems = query.Split('&');

            Dictionary <string, string> queries = new Dictionary <string, string>();

            foreach (string item in queryItems)
            {
                if (item.StartsWith("$select=", StringComparison.Ordinal))
                {
                    queries["$select"] = item.Substring(8);
                }
                else if (item.StartsWith("$expand=", StringComparison.Ordinal))
                {
                    queries["$expand"] = item.Substring(8);
                }
                else if (item.StartsWith("$filter=", StringComparison.Ordinal))
                {
                    queries["$filter"] = item.Substring(8);
                }
                else if (item.StartsWith("$orderby=", StringComparison.Ordinal))
                {
                    queries["$orderby"] = item.Substring(9);
                }
                else if (item.StartsWith("$compute=", StringComparison.Ordinal))
                {
                    queries["$compute"] = item.Substring(9);
                }
            }

            ODataQueryOptionParser parser = new ODataQueryOptionParser(model, entityType, entitySet, queries);

            return(new QueryClause
            {
                Filter = parser.ParseFilter(),
                OrderBy = parser.ParseOrderBy(),
                SelectExpand = parser.ParseSelectAndExpand(),
                Compute = parser.ParseCompute()
            });
        }
        internal void AddAutoSelectExpandProperties()
        {
            bool containsAutoSelectExpandProperties = false;
            var  autoExpandRawValue = GetAutoExpandRawValue();
            var  autoSelectRawValue = GetAutoSelectRawValue();

            IDictionary <string, string> queryParameters = GetODataQueryParameters();

            if (!String.IsNullOrEmpty(autoExpandRawValue) && !autoExpandRawValue.Equals(RawValues.Expand, StringComparison.Ordinal))
            {
                queryParameters["$expand"]         = autoExpandRawValue;
                containsAutoSelectExpandProperties = true;
            }
            else
            {
                autoExpandRawValue = RawValues.Expand;
            }

            if (!String.IsNullOrEmpty(autoSelectRawValue) && !autoSelectRawValue.Equals(RawValues.Select, StringComparison.Ordinal))
            {
                queryParameters["$select"]         = autoSelectRawValue;
                containsAutoSelectExpandProperties = true;
            }
            else
            {
                autoSelectRawValue = RawValues.Select;
            }

            if (containsAutoSelectExpandProperties)
            {
                _queryOptionParser = new ODataQueryOptionParser(
                    Context.Model,
                    Context.ElementType,
                    Context.NavigationSource,
                    queryParameters,
                    Context.RequestContainer); // the Context.RequestContainer could be null for non-edm model
                var originalSelectExpand = SelectExpand;
                SelectExpand = new SelectExpandQueryOption(
                    autoSelectRawValue,
                    autoExpandRawValue,
                    Context,
                    _queryOptionParser);
                if (originalSelectExpand != null && originalSelectExpand.LevelsMaxLiteralExpansionDepth > 0)
                {
                    SelectExpand.LevelsMaxLiteralExpansionDepth = originalSelectExpand.LevelsMaxLiteralExpansionDepth;
                }
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataQueryOptions"/> class based on the incoming request and some metadata information from
        /// the <see cref="ODataQueryContext"/>.
        /// </summary>
        /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information.</param>
        /// <param name="request">The incoming request message.</param>
        public ODataQueryOptions(ODataQueryContext context, HttpRequestMessage request)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            if (request.GetConfiguration() != null)
            {
                _assembliesResolver = request.GetConfiguration().Services.GetAssembliesResolver();
            }

            // fallback to the default assemblies resolver if none available.
            _assembliesResolver = _assembliesResolver ?? new DefaultAssembliesResolver();

            // remember the context and request
            Context = context;
            Request = request;

            // Parse the query from request Uri
            RawValues = new ODataRawQueryOptions();
            IDictionary <string, string> queryParameters =
                request.GetQueryNameValuePairs().ToDictionary(p => p.Key, p => p.Value);

            _queryOptionParser = new ODataQueryOptionParser(
                context.Model,
                context.ElementType,
                context.NavigationSource,
                queryParameters);

            HttpConfiguration configuration = Request.GetConfiguration();

            if (configuration != null)
            {
                ODataUriResolverSetttings resolverSettings = configuration.GetResolverSettings();
                _queryOptionParser.Resolver = resolverSettings.CreateResolver(context.Model);
            }

            BuildQueryOptions(queryParameters);

            Validator = new ODataQueryValidator();
        }
        private ApplyClause CreateApplyNode(string clause, IEdmModel model, Type entityType)
        {
            IEdmEntityType productType = model.SchemaElements.OfType <IEdmEntityType>().Single(t => t.Name == entityType.Name);

            Assert.NotNull(productType); // Guard

            IEdmEntitySet products = model.EntityContainer.FindEntitySet("Products");

            Assert.NotNull(products); // Guard

            ODataQueryOptionParser parser = new ODataQueryOptionParser(model, productType, products,
                                                                       new Dictionary <string, string> {
                { "$apply", clause }
            });

            return(parser.ParseApply());
        }
Esempio n. 16
0
        private static FilterClause CreateFilterClause(string filter, IEdmModel model, Type type)
        {
            IEdmEntityType entityType = model.SchemaElements.OfType <IEdmEntityType>().Single(t => t.Name == type.Name);

            Assert.NotNull(entityType); // Guard

            IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Products");

            Assert.NotNull(entitySet); // Guard

            ODataQueryOptionParser parser = new ODataQueryOptionParser(model, entityType, entitySet,
                                                                       new Dictionary <string, string> {
                { "$filter", filter }
            });

            return(parser.ParseFilter());
        }
        /// <summary>
        /// Apply $top and $skip parameters to query.
        /// </summary>
        /// <typeparam name="T">The type param</typeparam>
        /// <param name="query">The OData aware query.</param>
        /// <param name="topText">$top parameter value</param>
        /// <param name="skipText">$skip parameter value</param>
        /// <param name="entitySetName">The entity set name.</param>
        /// <returns>The <see cref="ODataQuery{T}"/> query with applied $top and $skip parameters.</returns>
        public static ODataQuery <T> TopSkip <T>(this ODataQuery <T> query, string topText = null, string skipText = null, string entitySetName = null)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            ODataSettings settings = query.ServiceProvider.GetRequiredService <ODataSettings>();

            Dictionary <string, string> dictionary = new Dictionary <string, string>();

            if (topText != null)
            {
                dictionary.Add("$top", topText);
            }

            if (skipText != null)
            {
                dictionary.Add("$skip", skipText);
            }

            ODataQueryOptionParser queryOptionParser = GetParser(
                query,
                entitySetName,
                dictionary);

            long?skip = queryOptionParser.ParseSkip();
            long?top  = queryOptionParser.ParseTop();

            if (skip.HasValue || top.HasValue || settings.QuerySettings.PageSize.HasValue)
            {
                IQueryable <T> result = TopSkipHelper.ApplySkipWithValidation(query, skip, settings);
                if (top.HasValue)
                {
                    result = TopSkipHelper.ApplyTopWithValidation(result, top, settings);
                }
                else
                {
                    result = TopSkipHelper.ApplyTopWithValidation(result, settings.QuerySettings.PageSize, settings);
                }

                return(new ODataQuery <T>(result, query.ServiceProvider));
            }

            return(query);
        }
Esempio n. 18
0
        private static void GetGroupByParams(string value, out IQueryable data, out ODataQueryContext context, out ODataQuerySettings settings,
                                             out ApplyGroupbyClause groupByClause, out DefaultAssembliesResolver assembliesResolver,
                                             out GroupByImplementation groupByImplementation, out Type keyType, out IEnumerable <LambdaExpression> propertiesToGroupByExpressions)
        {
            string queryOption = "$apply";

            data     = TestDataSource.CreateData();
            settings = new ODataQuerySettings()
            {
                PageSize = 2000,
                HandleNullPropagation = HandleNullPropagationOption.False
            };
            var _settings = settings;

            var model = TestModelBuilder.CreateModel(new Type[] { typeof(Category), typeof(Product), typeof(Sales) });

            context = new ODataQueryContext(model, typeof(Sales),
                                            new ODataPath(new ODataPathSegment[] { new EntitySetPathSegment("Sales") }));
            var _context = context;

            IEdmNavigationSource source = model.FindDeclaredEntitySet("Sales");
            var parser = new ODataQueryOptionParser(model,
                                                    model.FindDeclaredType("System.Web.OData.Aggregation.Tests.Common.Sales"),
                                                    source,
                                                    new Dictionary <string, string>()
            {
                { queryOption, value }
            });

            var applyCaluse = parser.ParseApply();

            groupByClause      = applyCaluse.Transformations.First().Item2 as ApplyGroupbyClause;
            assembliesResolver = new DefaultAssembliesResolver();
            var _assembliesResolver = assembliesResolver;

            groupByImplementation = new GroupByImplementation()
            {
                Context = context
            };
            keyType = groupByImplementation.GetGroupByKeyType(groupByClause);
            var entityParam = Expression.Parameter(context.ElementClrType, "$it");

            propertiesToGroupByExpressions = groupByClause.SelectedPropertiesExpressions.Select(
                exp =>
                FilterBinder.Bind(exp, _context.ElementClrType, _context.Model, _assembliesResolver, _settings, entityParam));
        }
        public static ODataQueryOptionParser GetParser <T>(ODataQuery <T> query, string entitySetName, IDictionary <string, string> raws)
        {
            IEdmModel edmModel = query.EdmModel;

            if (entitySetName == null)
            {
                entitySetName = typeof(T).Name;
            }

            IEdmEntityContainer[] containers =
                edmModel.SchemaElements.Where(
                    e => e.SchemaElementKind == EdmSchemaElementKind.EntityContainer &&
                    (e as IEdmEntityContainer).FindEntitySet(entitySetName) != null)
                .OfType <IEdmEntityContainer>()
                .ToArray();

            if (containers.Length == 0)
            {
                throw new ArgumentException($"Unable to find {entitySetName} entity set in the model.",
                                            nameof(entitySetName));
            }

            if (containers.Length > 1)
            {
                throw new ArgumentException($"Entity Set {entitySetName} found more that 1 time",
                                            nameof(entitySetName));
            }

            IEdmEntitySet entitySet = containers.Single().FindEntitySet(entitySetName);

            if (entitySet == null)
            {
            }

            ODataPath path = new ODataPath(new EntitySetSegment(entitySet));

            ODataQueryOptionParser parser = new ODataQueryOptionParser(edmModel, path, raws, query.ServiceProvider);

            ODataSettings settings = query.ServiceProvider.GetRequiredService <ODataSettings>();

            // Workaround for strange behavior in QueryOptionsParserConfiguration constructor which set it to false always
            parser.Resolver.EnableCaseInsensitive = settings.EnableCaseInsensitive;

            return(parser);
        }
Esempio n. 20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataQueryOptions"/> class based on the incoming request and some metadata information from
        /// the <see cref="ODataQueryContext"/>.
        /// </summary>
        /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information.</param>
        /// <param name="request">The incoming request message.</param>
        public ODataQueryOptions(ODataQueryContext context, HttpRequestMessage request)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            // Set the request container into context
            Contract.Assert(context.RequestContainer == null);
            context.RequestContainer = request.GetRequestContainer();

            // Remember the context and request
            Context = context;
            Request = request;

            ODataUriResolver uriResolver = request.GetRequestContainer().GetRequiredService <ODataUriResolver>();

            if (uriResolver != null)
            {
                _enableNoDollarSignQueryOptions = uriResolver.EnableNoDollarQueryOptions;
            }

            // Parse the query from request Uri, including only keys which are OData query parameters or parameter alias
            // OData query parameters are normalized with the $-sign prefixes when the
            // <code>EnableNoDollarSignPrefixSystemQueryOption</code> option is used.
            RawValues = new ODataRawQueryOptions();
            IDictionary <string, string> normalizedqueryParameters = GetODataQueryParameters();

            _queryOptionParser = new ODataQueryOptionParser(
                context.Model,
                context.ElementType,
                context.NavigationSource,
                normalizedqueryParameters);

            _queryOptionParser.Resolver = uriResolver;

            BuildQueryOptions(normalizedqueryParameters);

            Validator = ODataQueryValidator.GetODataQueryValidator(context);
        }
        private static OrderByClause TranslateParameterAlias(OrderByClause orderBy, ODataQueryOptionParser queryOptionParser)
        {
            if (orderBy == null)
            {
                return(null);
            }

            SingleValueNode orderByExpression = orderBy.Expression.Accept(
                new ParameterAliasNodeTranslator(queryOptionParser.ParameterAliasNodes)) as SingleValueNode;

            orderByExpression = orderByExpression ?? new ConstantNode(null, "null");

            return(new OrderByClause(
                       TranslateParameterAlias(orderBy.ThenBy, queryOptionParser),
                       orderByExpression,
                       orderBy.Direction,
                       orderBy.RangeVariable));
        }
    public IEnumerable <ProductDTO> Get(ODataQueryOptions <ProductDTO> q)
    {
        IQueryable <Product>   products = this._products.AsQueryable();
        IEdmModel              model    = GetModel();
        IEdmType               type     = model.FindDeclaredType("TestAPI.Models.Product");
        IEdmNavigationSource   source   = model.FindDeclaredEntitySet("Products");
        ODataQueryOptionParser parser   = new ODataQueryOptionParser(model, type, source, new Dictionary <string, string> {
            { "$filter", q.Filter.RawValue }
        });
        ODataQueryContext context = new ODataQueryContext(model, typeof(Product), q.Context.Path);
        FilterQueryOption filter  = new FilterQueryOption(q.Filter.RawValue, context, parser);

        if (filter != null)
        {
            products = filter.ApplyTo(products, new ODataQuerySettings()) as IQueryable <Product>;
        }
        return(products.Select(p => new ProductDTO(p)));
    }
Esempio n. 23
0
        private FilterClause CreateFilterClause(string filterExpression)
        {
            const string uriBase = "http://service/";

            Uri            uri       = new Uri(uriBase + "Pet1Set?$filter=" + filterExpression);
            ODataUriParser parser    = new ODataUriParser(HardCodedTestModel.TestModel, new Uri(uriBase), uri);
            IEdmEntitySet  entitySet = HardCodedTestModel.GetPet1Set();

            Dictionary <string, string> queryOptions = new Dictionary <string, string>()
            {
                { "$filter", filterExpression }
            };

            // Use query option parser to help create the filter because it takes care of a bunch of instantiations
            ODataQueryOptionParser queryOptionParser =
                new ODataQueryOptionParser(HardCodedTestModel.TestModel, entitySet.EntityType(), entitySet, queryOptions);

            return(queryOptionParser.ParseFilter());
        }
Esempio n. 24
0
        public void CreatePropertyValueExpressionWithFilter_Collection_Works_HandleNullPropagationOptionIsTrue()
        {
            // Arrange
            _model.Model.SetAnnotationValue(_model.Order, new ClrTypeAnnotation(typeof(Order)));
            _settings.HandleNullPropagation = HandleNullPropagationOption.True;
            var customer =
                Expression.Constant(new Customer {
                Orders = new[] { new Order {
                                     ID = 1
                                 }, new Order {
                                     ID = 2
                                 } }
            });
            var ordersProperty = _model.Customer.NavigationProperties().Single(p => p.Name == "Orders");
            var parser         = new ODataQueryOptionParser(
                _model.Model,
                _model.Order,
                _model.Orders,
                new Dictionary <string, string> {
                { "$filter", "ID eq 1" }
            });
            var filterCaluse = parser.ParseFilter();

            // Act
            var filterInExpand = _binder.CreatePropertyValueExpressionWithFilter(
                _model.Customer,
                ordersProperty,
                customer,
                filterCaluse);

            // Assert
            Assert.Equal(
                string.Format(
                    "IIF((value({0}) == null), null, IIF((value({0}).Orders == null), null, " +
                    "value({0}).Orders.AsQueryable().Where($it => ($it.ID == value({1}).TypedProperty))))",
                    customer.Type,
                    "Microsoft.AspNet.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.Int32]"),
                filterInExpand.ToString());
            var orders = Expression.Lambda(filterInExpand).Compile().DynamicInvoke() as IEnumerable <Order>;

            Assert.Single(orders);
            Assert.Equal(1, orders.ToList()[0].ID);
        }
        [InlineData("NS.*", null, true, "specialUpgrade,upgrade")]                         // select wild card actions -> select all
        public void GetActionsToBeSelected_Selects_ExpectedActions(
            string select, string expand, bool specialCustomer, string actionsToSelect)
        {
            // Arrange
            ODataQueryOptionParser parser = new ODataQueryOptionParser(_model.Model, _model.Customer, _model.Customers,
                                                                       new Dictionary <string, string> {
                { "$select", select }, { "$expand", expand }
            });
            SelectExpandClause selectExpandClause = parser.ParseSelectAndExpand();

            IEdmEntityType entityType = specialCustomer ? _model.SpecialCustomer : _model.Customer;

            // Act
            SelectExpandNode selectExpandNode = new SelectExpandNode(selectExpandClause, entityType, _model.Model);
            var result = selectExpandNode.SelectedActions;

            // Assert
            Assert.Equal(actionsToSelect, String.Join(",", result.Select(p => p.Name).OrderBy(n => n)));
        }
Esempio n. 26
0
        public void CreatePropertyValueExpressionWithFilter_ThrowsODataException_IfMappingTypeIsNotFoundInModel()
        {
            // Arrange
            _model.Model.SetAnnotationValue <ClrTypeAnnotation>(_model.Order, value: null);
            var customer       = Expression.Constant(new Customer());
            var ordersProperty = _model.Customer.NavigationProperties().Single(p => p.Name == "Orders");
            var parser         = new ODataQueryOptionParser(
                _model.Model,
                _model.Order,
                _model.Orders,
                new Dictionary <string, string> {
                { "$filter", "ID eq 1" }
            });
            var filterCaluse = parser.ParseFilter();

            // Act & Assert
            Assert.Throws <ODataException>(
                () => _binder.CreatePropertyValueExpressionWithFilter(_model.Customer, ordersProperty, customer, filterCaluse),
                "The provided mapping does not contain an entry for the entity type 'NS.Order'.");
        }
Esempio n. 27
0
        /// <summary>
        /// Initialize a new instance of <see cref="FilterQueryOption"/> based on the raw $filter value and
        /// an EdmModel from <see cref="ODataQueryContext"/>.
        /// </summary>
        /// <param name="rawValue">The raw value for $filter query. It can be null or empty.</param>
        /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information</param>
        /// <param name="queryOptionParser">The <see cref="ODataQueryOptionParser"/> which is used to parse the query option.</param>
        public FilterQueryOption(string rawValue, ODataQueryContext context, ODataQueryOptionParser queryOptionParser)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            if (String.IsNullOrEmpty(rawValue))
            {
                throw Error.ArgumentNullOrEmpty("rawValue");
            }

            if (queryOptionParser == null)
            {
                throw Error.ArgumentNull("queryOptionParser");
            }

            Context            = context;
            RawValue           = rawValue;
            _queryOptionParser = queryOptionParser;
        }
Esempio n. 28
0
        public void ProjectAsWrapper_Element_ProjectedValueDoesNotContainInstance_IfSelectionIsPartial()
        {
            // Arrange
            Customer customer             = new Customer();
            ODataQueryOptionParser parser = new ODataQueryOptionParser(_model.Model, _model.Customer, _model.Customers,
                                                                       new Dictionary <string, string> {
                { "$select", "ID,Orders" }, { "$expand", "Orders" }
            });
            SelectExpandClause selectExpand = parser.ParseSelectAndExpand();
            Expression         source       = Expression.Constant(customer);

            // Act
            Expression projection = _binder.ProjectAsWrapper(source, selectExpand, _model.Customer, _model.Customers);

            // Assert
            Assert.Equal(ExpressionType.MemberInit, projection.NodeType);
            Assert.NotEmpty((projection as MemberInitExpression).Bindings.Where(p => p.Member.Name == "Instance"));
            SelectExpandWrapper <Customer> customerWrapper = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper <Customer>;

            Assert.Same(customer, customerWrapper.Instance);
        }
        public void GetPropertiesToBeSelected_Selects_ExpectedProperties_OnExpandedOrders(
            string select, string expand, bool specialOrder, string structuralPropertiesToSelect)
        {
            // Arrange
            ODataQueryOptionParser parser = new ODataQueryOptionParser(_model.Model, _model.Customer, _model.Customers,
                                                                       new Dictionary <string, string> {
                { "$select", select }, { "$expand", expand }
            });
            SelectExpandClause selectExpandClause = parser.ParseSelectAndExpand();

            SelectExpandClause nestedSelectExpandClause = selectExpandClause.SelectedItems.OfType <ExpandedNavigationSelectItem>().Single().SelectAndExpand;

            IEdmEntityType entityType = specialOrder ? _model.SpecialOrder : _model.Order;

            // Act
            SelectExpandNode selectExpandNode = new SelectExpandNode(nestedSelectExpandClause, entityType, _model.Model);
            var result = selectExpandNode.SelectedStructuralProperties;

            // Assert
            Assert.Equal(structuralPropertiesToSelect, String.Join(",", result.Select(p => p.Name).OrderBy(n => n)));
        }
Esempio n. 30
0
        public void ProjectAsWrapper_Element_ProjectedValueContains_SelectedStructuralProperties()
        {
            // Arrange
            Customer customer = new Customer {
                Name = "OData"
            };
            ODataQueryOptionParser parser = new ODataQueryOptionParser(_model.Model, _model.Customer, _model.Customers,
                                                                       new Dictionary <string, string> {
                { "$select", "Name,Orders" }, { "$expand", "Orders" }
            });
            SelectExpandClause selectExpand = parser.ParseSelectAndExpand();
            Expression         source       = Expression.Constant(customer);

            // Act
            Expression projection = _binder.ProjectAsWrapper(source, selectExpand, _model.Customer, _model.Customers);

            // Assert
            SelectExpandWrapper <Customer> customerWrapper = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper <Customer>;

            Assert.Equal(customer.Name, customerWrapper.Container.ToDictionary(new IdentityPropertyMapper())["Name"]);
        }