public EdmEntityObjectCollection Get()
        {
            // Get Edm type from request.
            ODataPath path = Request.ODataProperties().Path;
            IEdmType edmType = path.EdmType;
            Contract.Assert(edmType.TypeKind == EdmTypeKind.Collection);

            IEdmCollectionType collectionType = edmType as IEdmCollectionType;
            IEdmEntityType entityType = collectionType.ElementType.Definition as IEdmEntityType;
            IEdmModel model = Request.ODataProperties().Model;

            ODataQueryContext queryContext = new ODataQueryContext(model, entityType, path);
            ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, Request);

            // Apply the query option on the IQueryable here.

            return new EdmEntityObjectCollection(new EdmCollectionTypeReference(collectionType), Products.ToList());
        }
        private object ExecuteQuery(object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)
        {
            Type elementClrType = GetElementType(response, actionDescriptor);

            IEdmModel model = GetModel(elementClrType, request, actionDescriptor);
            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.QueryGetModelMustNotReturnNull);
            }

            ODataQueryContext queryContext = new ODataQueryContext(model, elementClrType);
            ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, request);
            ValidateQuery(request, queryOptions);

            // apply the query
            IEnumerable enumerable = response as IEnumerable;
            if (enumerable == null)
            {
                // response is not a collection; we only support $select and $expand on single entities.
                ValidateSelectExpandOnly(queryOptions);

                SingleResult singleResult = response as SingleResult;
                if (singleResult == null)
                {
                    // response is a single entity.
                    return ApplyQuery(entity: response, queryOptions: queryOptions);
                }
                else
                {
                    // response is a composable SingleResult. ApplyQuery and call SingleOrDefault.
                    IQueryable queryable = singleResult.Queryable;
                    queryable = ApplyQuery(queryable, queryOptions);
                    return SingleOrDefault(queryable, actionDescriptor);
                }
            }
            else
            {
                // response is a collection.
                IQueryable queryable = (enumerable as IQueryable) ?? enumerable.AsQueryable();
                return ApplyQuery(queryable, queryOptions);
            }
        }
Exemplo n.º 3
0
 public static ODataQueryOptions CreateQueryOptions(IEdmModel model, Type elementClrType, HttpRequestMessage request)
 {
     var context = new ODataQueryContext(model, elementClrType, null);
     var queryOptions = new ODataQueryOptions(context, request);
     return queryOptions;
 }
Exemplo n.º 4
0
        private IQueryable GetQuery()
        {
            ODataPath path = this.GetPath();

            RestierQueryBuilder builder = new RestierQueryBuilder(this.Api, path);
            IQueryable queryable = builder.BuildQuery();
            this.shouldReturnCount = builder.IsCountPathSegmentPresent;
            this.shouldWriteRawValue = builder.IsValuePathSegmentPresent;
            if (queryable == null)
            {
                throw new HttpResponseException(
                    this.Request.CreateErrorResponse(
                        HttpStatusCode.NotFound,
                        Resources.ResourceNotFound));
            }

            if (this.shouldReturnCount || this.shouldWriteRawValue)
            {
                // Query options don't apply to $count or $value.
                return queryable;
            }

            ODataQueryContext queryContext =
                new ODataQueryContext(this.Request.ODataProperties().Model, queryable.ElementType, path);
            ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, this.Request);

            // TODO GitHubIssue#41 : Ensure stable ordering for query
            ODataQuerySettings settings = new ODataQuerySettings()
            {
                HandleNullPropagation = HandleNullPropagationOption.False,
                EnsureStableOrdering = true,
                EnableConstantParameterization = false,
                PageSize = null,  // no support for server enforced PageSize, yet
            };

            queryable = queryOptions.ApplyTo(queryable, settings);

            return queryable;
        }
Exemplo n.º 5
0
        private object ExecuteQuery(object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)
        {
            Type elementClrType = GetElementType(response, actionDescriptor);

            IEdmModel model = GetModel(elementClrType, request, actionDescriptor);
            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.QueryGetModelMustNotReturnNull);
            }

            ODataQueryContext queryContext = new ODataQueryContext(
                model,
                elementClrType,
                request.ODataProperties().Path);
            ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, request);

            if (queryOptions.SelectExpand != null)
            {
                queryOptions.SelectExpand.LevelsMaxLiteralExpansionDepth = _validationSettings.MaxExpansionDepth;
            }

            ValidateQuery(request, queryOptions);

            // apply the query
            IEnumerable enumerable = response as IEnumerable;
            if (enumerable == null)
            {
                // response is not a collection; we only support $select and $expand on single entities.
                ValidateSelectExpandOnly(queryOptions);

                SingleResult singleResult = response as SingleResult;
                if (singleResult == null)
                {
                    // response is a single entity.
                    return ApplyQuery(entity: response, queryOptions: queryOptions);
                }
                else
                {
                    // response is a composable SingleResult. ApplyQuery and call SingleOrDefault.
                    IQueryable queryable = singleResult.Queryable;
                    queryable = ApplyQuery(queryable, queryOptions);
                    return SingleOrDefault(queryable, actionDescriptor);
                }
            }
            else
            {
                // response is a collection.
                IQueryable queryable = (enumerable as IQueryable) ?? enumerable.AsQueryable();
                queryable = ApplyQuery(queryable, queryOptions);

                if (ODataCountMediaTypeMapping.IsCountRequest(request))
                {
                    long? count = request.ODataProperties().TotalCount;

                    if (count.HasValue)
                    {
                        // Return the count value if it is a $count request.
                        return count.Value;
                    }
                }

                return queryable;
            }
        }
        public IHttpActionResult Get([FromODataUri] int key)
        {
            object id;
            if (postedCustomer == null || !postedCustomer.TryGetPropertyValue("Id", out id) || key != (int)id)
            {
                return BadRequest("The key isn't the one posted to the customer");
            }

            ODataQueryContext context = new ODataQueryContext(Request.ODataProperties().Model, CustomerType, path: null);
            ODataQueryOptions query = new ODataQueryOptions(context, Request);
            if (query.SelectExpand != null)
            {
                Request.ODataProperties().SelectExpandClause = query.SelectExpand.SelectExpandClause;
            }
            return Ok(postedCustomer);
        }
Exemplo n.º 7
0
 private ODataQueryOptions BuildQueryOptions()
 {
     ODataPath path = Request.ODataProperties().Path;
     IEdmType edmType = path.Segments[0].GetEdmType(path.EdmType);
     IEdmType elementType = edmType.TypeKind == EdmTypeKind.Collection
         ? (edmType as IEdmCollectionType).ElementType.Definition
         : edmType;
     ODataQueryContext queryContext = new ODataQueryContext(Request.ODataProperties().Model, elementType, path);
     ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, Request);
     return queryOptions;
 }
Exemplo n.º 8
0
        public HttpResponseMessage PostComplexFunction()
        {
            ODataPath path = Request.ODataProperties().Path;
            UnboundFunctionPathSegment seg = path.Segments.FirstOrDefault() as UnboundFunctionPathSegment;
            IEdmType edmType = seg.Function.Function.ReturnType.Definition;
            IEdmType elementType = edmType.TypeKind == EdmTypeKind.Collection
                ? (edmType as IEdmCollectionType).ElementType.Definition
                : edmType;
            ODataQueryContext queryContext = new ODataQueryContext(Request.ODataProperties().Model, elementType, path);
            ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, Request);
            JObject jobj = null;
            if (Request.Content.IsFormData())
            {
                jobj = Request.Content.ReadAsAsync<JObject>().Result;
            }
            else
            {
                string s = Request.Content.ReadAsStringAsync().Result;
                if (!string.IsNullOrEmpty(s))
                    jobj = JObject.Parse(s);
            }
            string dsName = (string)Request.Properties[Constants.ODataDataSource];
            var ds = DataSourceProvider.GetDataSource(dsName);
            var ri = new RequestInfo(dsName)
            {
                Method = MethodType.Func,
                Parameters = jobj,
                Target = seg.FunctionName,
                QueryOptions = queryOptions
            };
            if (DynamicOData.BeforeExcute != null)
            {
                DynamicOData.BeforeExcute(ri);
                if (!ri.Result)
                    return Request.CreateResponse(ri.StatusCode, ri.Message);
            }
            try
            {
                var b = ds.InvokeFunction(seg.Function.Function, ri.Parameters, ri.QueryOptions);

                if (b is EdmComplexObjectCollection)
                    return Request.CreateResponse(HttpStatusCode.OK, b as EdmComplexObjectCollection);
                else
                    return Request.CreateResponse(HttpStatusCode.OK, b as EdmComplexObject);
            }
            catch (UnauthorizedAccessException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, ex);
            }
            catch (Exception err)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, err);
            }
        }
Exemplo n.º 9
0
        public HttpResponseMessage GetSimpleFunction()
        {
            ODataPath path = Request.ODataProperties().Path;

            UnboundFunctionPathSegment seg = path.Segments.FirstOrDefault() as UnboundFunctionPathSegment;
            IEdmType edmType = seg.Function.Function.ReturnType.Definition;

            IEdmType elementType = edmType.TypeKind == EdmTypeKind.Collection
                ? (edmType as IEdmCollectionType).ElementType.Definition
                : edmType;
            ODataQueryContext queryContext = new ODataQueryContext(Request.ODataProperties().Model, elementType, path);
            ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, Request);

            string dsName = (string)Request.Properties[Constants.ODataDataSource];
            var ds = DataSourceProvider.GetDataSource(dsName);
            JObject pars = new JObject();
            foreach (var p in seg.Function.Function.Parameters)
            {
                try
                {
                    var n = seg.GetParameterValue(p.Name);
                    pars.Add(p.Name, new JValue(n));
                }
                catch { }
            }
            var ri = new RequestInfo(dsName)
            {
                Method = MethodType.Func,
                Parameters = pars,
                Target = seg.FunctionName,
                QueryOptions = queryOptions
            };
            if (DynamicOData.BeforeExcute != null)
            {
                DynamicOData.BeforeExcute(ri);
                if (!ri.Result)
                    return Request.CreateResponse(ri.StatusCode, ri.Message);
            }
            try
            {
                var b = ds.InvokeFunction(seg.Function.Function, ri.Parameters, ri.QueryOptions);
                if (b is EdmComplexObjectCollection)
                    return Request.CreateResponse(HttpStatusCode.OK, b as EdmComplexObjectCollection);
                else
                    return Request.CreateResponse(HttpStatusCode.OK, b as EdmComplexObject);
            }
            catch (UnauthorizedAccessException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, ex);
            }
            catch (Exception err)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, err);
            }
        }
Exemplo n.º 10
0
        private IQueryable GetQuery()
        {
            ODataPath path = this.GetPath();

            RestierQueryBuilder builder = new RestierQueryBuilder(this.Api, path);
            IQueryable queryable = builder.BuildQuery();
            this.shouldReturnCount = builder.IsCountPathSegmentPresent;
            this.shouldWriteRawValue = builder.IsValuePathSegmentPresent;
            if (queryable == null)
            {
                throw new HttpResponseException(
                    this.Request.CreateErrorResponse(
                        HttpStatusCode.NotFound,
                        Resources.ResourceNotFound));
            }

            if (this.shouldReturnCount || this.shouldWriteRawValue)
            {
                // Query options don't apply to $count or $value.
                return queryable;
            }

            ODataQueryContext queryContext =
                new ODataQueryContext(this.Request.ODataProperties().Model, queryable.ElementType, path);
            ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, this.Request);
            if (queryOptions.Count != null)
            {
                this.includeTotalCount = queryOptions.Count.Value;
            }

            // TODO GitHubIssue#41 : Ensure stable ordering for query
            ODataQuerySettings settings = new ODataQuerySettings
            {
                HandleNullPropagation = HandleNullPropagationOption.False,
                PageSize = null,  // no support for server enforced PageSize, yet
            };

            // Entity count can NOT be evaluated at this point of time because the source
            // expression is just a placeholder to be replaced by the expression sourcer.
            queryable = queryOptions.ApplyTo(queryable, settings, AllowedQueryOptions.Count);

            return queryable;
        }
Exemplo n.º 11
0
        private IQueryable ApplyQueryOptions(
            IQueryable queryable, ODataPath path, bool applyCount, out bool isIfNoneMatch, out ETag etag)
        {
            // ETAG IsIfNoneMatch is changed to public access, this flag can be removed.
            isIfNoneMatch = false;
            etag = null;

            if (this.shouldWriteRawValue)
            {
                // Query options don't apply to $value.
                return queryable;
            }

            HttpRequestMessageProperties properties = this.Request.ODataProperties();
            var model = Api.GetModelAsync().Result;
            ODataQueryContext queryContext =
                new ODataQueryContext(model, queryable.ElementType, path);
            ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, this.Request);

            // Get etag for query request
            if (queryOptions.IfMatch != null)
            {
                etag = queryOptions.IfMatch;
            }
            else if (queryOptions.IfNoneMatch != null)
            {
                isIfNoneMatch = true;
                etag = queryOptions.IfNoneMatch;
            }

            // TODO GitHubIssue#41 : Ensure stable ordering for query
            ODataQuerySettings settings = Api.Context.GetApiService<ODataQuerySettings>();

            if (this.shouldReturnCount)
            {
                // Query options other than $filter and $search don't apply to $count.
                queryable = queryOptions.ApplyTo(
                    queryable, settings, AllowedQueryOptions.All ^ AllowedQueryOptions.Filter);
                return queryable;
            }

            if (queryOptions.Count != null && !applyCount)
            {
                RestierQueryExecutorOptions queryExecutorOptions =
                    Api.Context.GetApiService<RestierQueryExecutorOptions>();
                queryExecutorOptions.IncludeTotalCount = queryOptions.Count.Value;
                queryExecutorOptions.SetTotalCount = value => properties.TotalCount = value;
            }

            // Validate query before apply, and query setting like MaxExpansionDepth can be customized here
            ODataValidationSettings validationSettings = Api.Context.GetApiService<ODataValidationSettings>();
            queryOptions.Validate(validationSettings);

            // Entity count can NOT be evaluated at this point of time because the source
            // expression is just a placeholder to be replaced by the expression sourcer.
            if (!applyCount)
            {
                queryable = queryOptions.ApplyTo(queryable, settings, AllowedQueryOptions.Count);
            }
            else
            {
                queryable = queryOptions.ApplyTo(queryable, settings);
            }

            return queryable;
        }
 public DerivedODataQueryOptions(ODataQueryContext context, HttpRequestMessage request)
     : base(context, request)
 {
 }