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); }
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); }
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)); }
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)); }