public void GetResultSize_ReturnsEffectivePageSize(string top, int? pageSize, int expected)
        {
            // Arrange
            ODataQueryContext context = new ODataQueryContext(EdmModelMock.Create<Movie>("Movies"), typeof(Movie));
            Uri address = new Uri("http://localhost?{0}".FormatInvariant(top));
            ODataQueryOptions query = new ODataQueryOptions(context, new HttpRequestMessage { RequestUri = address });
            ODataQuerySettings settings = new ODataQuerySettings() { PageSize = pageSize };

            // Act
            int actual = TableUtils.GetResultSize(query, settings);

            // Assert
            Assert.Equal(expected, actual);
        }
Пример #2
0
        public void TestFilterVisitor()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Bar>("Bar");

            ODataQueryContext context = new ODataQueryContext(builder.GetEdmModel(), typeof(Bar));
            //ODataQueryOptions<Customer> query = new ODataQueryOptions<Customer>(context, new HttpRequestMessage(HttpMethod.Get, "http://server/?$top=10"));

            FilterQueryOption f = new FilterQueryOption("startswith(BarString,'b') eq true", context);
            var fo = new FindNavigationFilterOptions();
            fo.Find(f.FilterClause.Expression);
            List<string> pathsString = fo.GetPaths();
            CollectionAssert.AreEqual(pathsString, new string[0]);

            f = new FilterQueryOption("F/FooId eq 1", context);
            fo = new FindNavigationFilterOptions();
            fo.Find(f.FilterClause.Expression);
            pathsString = fo.GetPaths();
            CollectionAssert.AreEqual(pathsString, new[] { "F" });

            f = new FilterQueryOption("(startswith(BarString,'b') eq true) and (not (Foos/any(x1: x1/B/BarId eq 1)))", context);
            fo = new FindNavigationFilterOptions();
            fo.Find(f.FilterClause.Expression);
            pathsString = fo.GetPaths();
            CollectionAssert.AreEqual(pathsString, new[] { "Foos.B" });

            f = new FilterQueryOption("Foos/any(x1: x1/B/BarId eq 1)", context);
            fo = new FindNavigationFilterOptions();
            fo.Find(f.FilterClause.Expression);
            pathsString = fo.GetPaths();
            CollectionAssert.AreEqual(pathsString, new[] { "Foos.B" });

            f = new FilterQueryOption("F/Bars/any(x1: x1/BarId eq 1)", context);
            fo = new FindNavigationFilterOptions();
            fo.Find(f.FilterClause.Expression);
            pathsString = fo.GetPaths();
            CollectionAssert.AreEqual(pathsString, new[] { "F.Bars" });


        }
        private IQueryable ExecuteQuery(IEnumerable query, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)
        {
            Type originalQueryType = query.GetType();
            Type elementClrType = TypeHelper.GetImplementedIEnumerableType(originalQueryType);

            if (elementClrType == null)
            {
                // The element type cannot be determined because the type of the content
                // is not IEnumerable<T> or IQueryable<T>.
                throw Error.InvalidOperation(
                    SRResources.FailedToRetrieveTypeToBuildEdmModel,
                    this.GetType().Name,
                    actionDescriptor.ActionName,
                    actionDescriptor.ControllerDescriptor.ControllerName,
                    originalQueryType.FullName);
            }

            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
            IQueryable queryable = query as IQueryable;
            if (queryable == null)
            {
                queryable = query.AsQueryable();
            }

            return ApplyQuery(queryable, queryOptions);
        }
Пример #4
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);
            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);
            }
        }
            public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
            {
                if (actionContext == null)
                {
                    throw Error.ArgumentNull("actionContext");
                }

                HttpRequestMessage request = actionContext.Request;

                if (request == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveRequest);
                }

                HttpActionDescriptor actionDescriptor = actionContext.ActionDescriptor;

                if (actionDescriptor == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveDescriptor);
                }

                HttpConfiguration configuration = request.GetConfiguration();

                if (configuration == null)
                {
                    throw Error.Argument("actionContext", SRResources.RequestMustContainConfiguration);
                }

                IEdmModel model = configuration.GetEdmModel();

                if (actionDescriptor.ReturnType == null)
                {
                    throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.InternalServerError,
                                 Error.Format(SRResources.FailedToBuildEdmModelBecauseReturnTypeIsNull,
                               actionDescriptor.ActionName, actionDescriptor.ControllerDescriptor.ControllerName)));
                }

                Type entityClrType = TypeHelper.GetImplementedIEnumerableType(actionDescriptor.ReturnType);

                if (entityClrType == null)
                {
                    throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.InternalServerError,
                           Error.Format(SRResources.FailedToRetrieveTypeToBuildEdmModel, actionDescriptor.ReturnType.FullName,
                               actionDescriptor.ActionName, actionDescriptor.ControllerDescriptor.ControllerName)));
                }

                if (model == null)
                {
                    model = actionDescriptor.GetEdmModel(entityClrType);
                }

                ODataQueryOptions parameterValue = null;
                ODataQueryContext entitySetContext = new ODataQueryContext(model, entityClrType);

                try
                {
                    parameterValue = new ODataQueryOptions(entitySetContext, request);
                    SetValue(actionContext, parameterValue);
                }
                catch (ODataException exception)
                {
                    throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.BadRequest, exception));
                }

                return TaskHelpers.FromResult(0);
            }
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext == null)
            {
                throw Error.ArgumentNull("actionExecutedContext");
            }

            HttpRequestMessage request = actionExecutedContext.Request;
            if (request == null)
            {
                throw Error.Argument("actionExecutedContext", SRResources.ActionExecutedContextMustHaveRequest);
            }

            HttpConfiguration configuration = request.GetConfiguration();
            if (configuration == null)
            {
                throw Error.Argument("actionExecutedContext", SRResources.RequestMustContainConfiguration);
            }

            if (actionExecutedContext.ActionContext == null)
            {
                throw Error.Argument("actionExecutedContext", SRResources.ActionExecutedContextMustHaveActionContext);
            }

            HttpActionDescriptor actionDescriptor = actionExecutedContext.ActionContext.ActionDescriptor;
            if (actionDescriptor == null)
            {
                throw Error.Argument("actionExecutedContext", SRResources.ActionContextMustHaveDescriptor);
            }

            HttpResponseMessage response = actionExecutedContext.Response;

            IEnumerable query;
            IQueryable queryable = null;
            if (response != null && response.IsSuccessStatusCode && response.TryGetContentValue(out query))
            {
                if (request.RequestUri != null && !String.IsNullOrWhiteSpace(request.RequestUri.Query))
                {
                    ValidateQuery(request);

                    try
                    {
                        ODataQueryContext queryContext;

                        Type originalQueryType = query.GetType();
                        Type entityClrType = TypeHelper.GetImplementedIEnumerableType(originalQueryType);

                        // Primitive types do not construct an EDM model and deal only with the CLR Type
                        if (TypeHelper.IsQueryPrimitiveType(entityClrType))
                        {
                            queryContext = new ODataQueryContext(entityClrType);
                        }
                        else
                        {
                            // Get model for the entire app
                            IEdmModel model = configuration.GetEdmModel();

                            if (entityClrType == null)
                            {
                                // The actual type is not IEnumerable or IQueryable
                                actionExecutedContext.Response = request.CreateErrorResponse(
                                   HttpStatusCode.InternalServerError,
                                   Error.Format(SRResources.FailedToRetrieveTypeToBuildEdmModel, originalQueryType.FullName,
                                       actionDescriptor.ActionName, actionDescriptor.ControllerDescriptor.ControllerName));
                                return;
                            }

                            if (model == null)
                            {
                                // user has not configured anything, now let's create one just for this type
                                // and cache it in the action descriptor
                                model = actionDescriptor.GetEdmModel(entityClrType);
                            }

                            if (model == null)
                            {
                                // we need to send 500 if we can't create a model
                                actionExecutedContext.Response = request.CreateErrorResponse(
                                    HttpStatusCode.InternalServerError,
                                    Error.Format(SRResources.FailedToBuildEdmModel, entityClrType.FullName,
                                        actionDescriptor.ActionName, actionDescriptor.ControllerDescriptor.ControllerName));
                                return;
                            }

                            // parses the query from request uri
                            queryContext = new ODataQueryContext(model, entityClrType);
                        }

                        ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, request);

                        // Filter and OrderBy require entity sets.  Top and Skip may accept primitives.
                        if (queryContext.IsPrimitiveClrType && (queryOptions.Filter != null || queryOptions.OrderBy != null))
                        {
                            // An attempt to use a query option not allowed for primitive types
                            // generates a BadRequest with a general message that avoids information disclosure.
                            actionExecutedContext.Response = request.CreateErrorResponse(
                                                                HttpStatusCode.BadRequest,
                                                                SRResources.OnlySkipAndTopSupported);
                            return;
                        }

                        // apply the query
                        queryable = query as IQueryable;
                        if (queryable == null)
                        {
                            queryable = query.AsQueryable();
                        }

                        if (_handleNullPropagation != null)
                        {
                            queryable = queryOptions.ApplyTo(queryable, _handleNullPropagation.Value);
                        }
                        else
                        {
                            queryable = queryOptions.ApplyTo(queryable);
                        }

                        Contract.Assert(queryable != null);

                        // we don't support shape changing query composition
                        ((ObjectContent)response.Content).Value = queryable;
                    }
                    catch (ODataException e)
                    {
                        actionExecutedContext.Response = request.CreateErrorResponse(
                            HttpStatusCode.BadRequest,
                            SRResources.UriQueryStringInvalid,
                            e);
                        return;
                    }
                }
            }
        }
 /// <summary>
 /// Applies the o data query.
 /// </summary>
 /// <param name="queryable">The queryable.</param>
 /// <param name="controller">The controller.</param>
 /// <param name="actionContext">The action context.</param>
 /// <param name="request">The request.</param>
 /// <returns></returns>
 public virtual IQueryable ApplyODataQuery(IQueryable queryable, ApiController controller, ActionContext actionContext, HttpRequestMessage request) {
     // if value is a query, first handle OData parameters
     var edmModel = GetModel(queryable.ElementType, request,
         new ReflectedHttpActionDescriptor(controller.ControllerContext.ControllerDescriptor, _dummyMethodInfo));
     // create necessary objects to query to be handled by WebApi
     var odataQueryContext = new ODataQueryContext(edmModel, queryable.ElementType);
     var odataQueryOptions = new ODataQueryOptions(odataQueryContext, request);
     // we need this to be able to access service in ApplyQuery method
     var service = controller as IBeetleService;
     request.Properties["BeetleService"] = service;
     request.Properties["BeetleActionContext"] = actionContext;
     // let WebApi engine apply the query
     queryable = ApplyQuery(queryable, odataQueryOptions);
     // apply skipped query parameters
     return FixODataQuery(queryable, request, service);
 }
        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);
            ODataQueryOptions query = new ODataQueryOptions(context, Request);
            if (query.SelectExpand != null)
            {
                Request.ODataProperties().SelectExpandClause = query.SelectExpand.SelectExpandClause;
            }
            return Ok(postedCustomer);
        }
            public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
            {
                if (actionContext == null)
                {
                    throw Error.ArgumentNull("actionContext");
                }

                HttpRequestMessage request = actionContext.Request;

                if (request == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveRequest);
                }

                HttpActionDescriptor actionDescriptor = actionContext.ActionDescriptor;

                if (actionDescriptor == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveDescriptor);
                }

                HttpConfiguration configuration = request.GetConfiguration();

                if (configuration == null)
                {
                    throw Error.Argument("actionContext", SRResources.RequestMustContainConfiguration);
                }

                IEdmModel model = configuration.GetEdmModel();

                // It is a developer programming error to use this binding attribute
                // on actions that return void.
                if (actionDescriptor.ReturnType == null)
                {
                    throw Error.InvalidOperation(
                                    SRResources.FailedToBuildEdmModelBecauseReturnTypeIsNull,
                                    this.GetType().Name,
                                    actionDescriptor.ActionName,
                                    actionDescriptor.ControllerDescriptor.ControllerName);
                }

                Type entityClrType = TypeHelper.GetImplementedIEnumerableType(actionDescriptor.ReturnType);

                if (entityClrType == null)
                {
                    // It is a developer programming error to use this binding attribute
                    // on actions that return a collection whose element type cannot be
                    // determined, such as a non-generic IQueryable or IEnumerable.
                    throw Error.InvalidOperation(
                                    SRResources.FailedToRetrieveTypeToBuildEdmModel,
                                    this.GetType().Name,
                                    actionDescriptor.ActionName, 
                                    actionDescriptor.ControllerDescriptor.ControllerName,
                                    actionDescriptor.ReturnType.FullName);
                }

                if (model == null)
                {
                    model = actionDescriptor.GetEdmModel(entityClrType);
                }

                ODataQueryOptions parameterValue = null;
                ODataQueryContext entitySetContext = new ODataQueryContext(model, entityClrType);

                try
                {
                    parameterValue = new ODataQueryOptions(entitySetContext, request);
                    SetValue(actionContext, parameterValue);
                }
                catch (ODataException exception)
                {
                    throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.BadRequest, exception));
                }

                return TaskHelpers.FromResult(0);
            }
        public static ODataQueryOptions <TEntity> CreateQueryOptions <TEntity>(ApiController controller)
        {
            ODataQueryContext context = new ODataQueryContext(controller.Request.GetEdmModel(), typeof(TEntity));

            return(new ODataQueryOptions <TEntity>(context, controller.Request));
        }
Пример #11
0
            public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
            {
                if (actionContext == null)
                {
                    throw Error.ArgumentNull("actionContext");
                }

                HttpRequestMessage request = actionContext.Request;

                if (request == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveRequest);
                }

                HttpActionDescriptor actionDescriptor = actionContext.ActionDescriptor;

                if (actionDescriptor == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveDescriptor);
                }

                HttpConfiguration configuration = request.GetConfiguration();

                if (configuration == null)
                {
                    throw Error.Argument("actionContext", SRResources.RequestMustContainConfiguration);
                }

                IEdmModel model = configuration.GetEdmModel();

                // It is a developer programming error to use this binding attribute
                // on actions that return void.
                if (actionDescriptor.ReturnType == null)
                {
                    throw Error.InvalidOperation(
                              SRResources.FailedToBuildEdmModelBecauseReturnTypeIsNull,
                              this.GetType().Name,
                              actionDescriptor.ActionName,
                              actionDescriptor.ControllerDescriptor.ControllerName);
                }

                Type entityClrType = TypeHelper.GetImplementedIEnumerableType(actionDescriptor.ReturnType);

                if (entityClrType == null)
                {
                    // It is a developer programming error to use this binding attribute
                    // on actions that return a collection whose element type cannot be
                    // determined, such as a non-generic IQueryable or IEnumerable.
                    throw Error.InvalidOperation(
                              SRResources.FailedToRetrieveTypeToBuildEdmModel,
                              this.GetType().Name,
                              actionDescriptor.ActionName,
                              actionDescriptor.ControllerDescriptor.ControllerName,
                              actionDescriptor.ReturnType.FullName);
                }

                if (model == null)
                {
                    model = actionDescriptor.GetEdmModel(entityClrType);
                }

                ODataQueryOptions parameterValue   = null;
                ODataQueryContext entitySetContext = new ODataQueryContext(model, entityClrType);

                try
                {
                    parameterValue = new ODataQueryOptions(entitySetContext, request);
                    SetValue(actionContext, parameterValue);
                }
                catch (ODataException exception)
                {
                    throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.BadRequest, exception));
                }

                return(TaskHelpers.FromResult(0));
            }