public override void OnResultExecuted(ResultExecutedContext resultExecutedContext)
        {
            base.OnResultExecuted(resultExecutedContext);

            if (resultExecutedContext == null)
            {
                throw new ArgumentNullException("resultExecutedContext", "Cannot apply OData Query with a null execution context.");
            }

            if (resultExecutedContext.HttpContext == null)
            {
                throw new ArgumentException("The HttpContext was null. Could not process OData Query request.");
            }

            var response = resultExecutedContext.HttpContext.Response;
            var request = resultExecutedContext.HttpContext.Request;

            var result = resultExecutedContext.Result;

            if (result != null)
            {
                var resultType = result.GetType();

                var responseType = resultType.GetGenericArguments().Single();

                var url = request.RawUrl;

                var uri = new Uri(url);

                var queryString = uri.Query;

                if (typeof (IQueryable).IsAssignableFrom(responseType) && (String.IsNullOrWhiteSpace(queryString) == false))
                {
                    var itemType = responseType.GetGenericArguments().Single();

                    var parser = new ODataUriParser(new ODataQueryParser(new ODataQueryPartParserStrategy()), new ExpressionODataQueryVisitor(new FilterExpressionBuilder()));

                    var expression = parser.Parse(itemType, uri);

                    var fn = expression.Compile();

                    // TODO: need to pass in current result here
                    var data = fn.DynamicInvoke();

                    var actionResult = Activator.CreateInstance(resultType) as ActionResult;

                    resultExecutedContext.Result = actionResult;
                }
            }
        }
        [InlineData("ID,Orders/ID,Orders/Customer/ID", "Orders,Orders/Customer", true, "ID")] // deep expand and selects
        public void GetPropertiesToBeSelected_Selects_ExpectedProperties_OnCustomer(
            string select, string expand, bool specialCustomer, string structuralPropertiesToSelect)
        {
            // Arrange
            SelectExpandClause selectExpandClause =
                new ODataUriParser(_model.Model, serviceRoot: null).ParseSelectAndExpand(select, expand, _model.Customer, _model.Customers);
            IEdmEntityType entityType = specialCustomer ? _model.SpecialCustomer : _model.Customer;

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

            // Assert
            Assert.Equal(structuralPropertiesToSelect, String.Join(",", result.Select(p => p.Name).OrderBy(n => n)));
        }
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext == null)
            {
                throw new ArgumentNullException(nameof (actionExecutedContext));
            }

            if (actionExecutedContext.Request == null)
            {
                throw new ArgumentException("The HttpActionExecutedContext cannot contain a null HttpRequestMessage.");
            }

            var request = actionExecutedContext.Request;
            var response = actionExecutedContext.Response;

            IQueryable query;
            if ((response != null) && response.TryGetContentValue(out query))
            {
                if ((request.RequestUri != null) && (String.IsNullOrWhiteSpace(request.RequestUri.Query) == false))
                {
                    var itemType = query.ElementType;

                    var requestUri = request.RequestUri;

                    var parser = new ODataUriParser(new ODataQueryParser(new ODataQueryPartParserStrategy()), new ExpressionODataQueryVisitor(new FilterExpressionBuilder()));

                    var expression = parser.Parse(itemType, requestUri);

                    var fn = expression.Compile();

                    var result = fn.DynamicInvoke(query);

                    var oldContent = (ObjectContent) response.Content;

                    var newContent = new ObjectContent(expression.ReturnType, result, oldContent.Formatter, oldContent.Headers.ContentType.MediaType);

                    response.Content = newContent;
                }
            }
        }
        [InlineData(null, "NS.SpecialCustomer/SpecialOrders", true, "SpecialOrders")] // expand derived navigation property on derived type -> expand requested
        public void GetNavigationPropertiesToBeExpanded_Expands_ExpectedProperties(
            string select, string expand, bool specialCustomer, string navigationPropertiesToExpand)
        {
            // Arrange
            SelectExpandClause selectExpandClause =
                new ODataUriParser(_model.Model, serviceRoot: null).ParseSelectAndExpand(select, expand, _model.Customer, _model.Customers);

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

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

            // Assert
            Assert.Equal(navigationPropertiesToExpand, String.Join(",", result.Select(p => p.Name).OrderBy(n => n)));
        }
        public void GetPropertiesToBeSelected_Selects_ExpectedProperties_OnExpandedOrders(
            string select, string expand, bool specialOrder, string structuralPropertiesToSelect)
        {
            // Arrange
            SelectExpandClause selectExpandClause =
                new ODataUriParser(_model.Model, serviceRoot: null).ParseSelectAndExpand(select, expand, _model.Customer, _model.Customers);
            SelectExpandClause nestedSelectExpandClause = selectExpandClause.SelectedItems.OfType<ExpandedNavigationSelectItem>().Single().SelectAndExpand;

            IEdmEntityTypeReference entityType = new EdmEntityTypeReference((specialOrder ? _model.SpecialOrder : _model.Order), false);

            // 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)));
        }
        [InlineData("ModelWithInheritance.*", null, true, "specialUpgrade,upgrade")] // select wild card actions -> select all
        public void GetActionsToBeSelected_Selects_ExpectedActions(
            string select, string expand, bool specialCustomer, string actionsToSelect)
        {
            // Arrange
            SelectExpandClause selectExpandClause =
                new ODataUriParser(_model.Model, serviceRoot: null).ParseSelectAndExpand(select, expand, _model.Customer, _model.Customers);
            IEdmEntityTypeReference entityType = new EdmEntityTypeReference(specialCustomer ? _model.SpecialCustomer : _model.Customer, false);

            // 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)));
        }
        public void WriteObjectInline_CanExpandNavigationProperty_ContainingEdmObject()
        {
            // Arrange
            IEdmEntityType customerType = _customerSet.ElementType;
            IEdmNavigationProperty ordersProperty = customerType.NavigationProperties().Single(p => p.Name == "Orders");

            Mock<IEdmObject> orders = new Mock<IEdmObject>();
            orders.Setup(o => o.GetEdmType()).Returns(ordersProperty.Type);
            object ordersValue = orders.Object;

            Mock<IEdmEntityObject> customer = new Mock<IEdmEntityObject>();
            customer.Setup(c => c.TryGetPropertyValue("Orders", out ordersValue)).Returns(true);
            customer.Setup(c => c.GetEdmType()).Returns(customerType.AsReference());

            SelectExpandClause selectExpandClause = new ODataUriParser(_model, serviceRoot: null).ParseSelectAndExpand("Orders", "Orders", customerType, _customerSet);
            SelectExpandNode selectExpandNode = new SelectExpandNode();
            selectExpandNode.ExpandedNavigationProperties[ordersProperty] = selectExpandClause.SelectedItems.OfType<ExpandedNavigationSelectItem>().Single().SelectAndExpand;

            Mock<ODataWriter> writer = new Mock<ODataWriter>();

            Mock<ODataEdmTypeSerializer> ordersSerializer = new Mock<ODataEdmTypeSerializer>(_serializer.EdmType, ODataPayloadKind.Entry);
            ordersSerializer.Setup(s => s.WriteObjectInline(ordersValue, writer.Object, It.IsAny<ODataSerializerContext>())).Verifiable();

            Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>();
            serializerProvider.Setup(p => p.GetEdmTypeSerializer(ordersProperty.Type)).Returns(ordersSerializer.Object);

            Mock<ODataEntityTypeSerializer> serializer = new Mock<ODataEntityTypeSerializer>(_serializer.EdmType, serializerProvider.Object);
            serializer.Setup(s => s.CreateSelectExpandNode(It.IsAny<EntityInstanceContext>())).Returns(selectExpandNode);
            serializer.CallBase = true;

            // Act
            serializer.Object.WriteObjectInline(customer.Object, writer.Object, _writeContext);

            //Assert
            ordersSerializer.Verify();
        }
        public void WriteObjectInline_ExpandsUsingInnerSerializerUsingRightContext_ExpandedNavigationProperties()
        {
            // Arrange
            IEdmEntityType customerType = _customerSet.ElementType;
            IEdmNavigationProperty ordersProperty = customerType.NavigationProperties().Single(p => p.Name == "Orders");
            SelectExpandClause selectExpandClause = new ODataUriParser(_model, serviceRoot: null).ParseSelectAndExpand("Orders", "Orders", customerType, _customerSet);
            SelectExpandNode selectExpandNode = new SelectExpandNode
            {
                ExpandedNavigationProperties = 
                { 
                    { ordersProperty, selectExpandClause.SelectedItems.OfType<ExpandedNavigationSelectItem>().Single().SelectAndExpand }
                }
            };
            Mock<ODataWriter> writer = new Mock<ODataWriter>();

            Mock<ODataEdmTypeSerializer> innerSerializer = new Mock<ODataEdmTypeSerializer>(_serializer.EdmType, ODataPayloadKind.Entry);
            innerSerializer
                .Setup(s => s.WriteObjectInline(_customer.Orders, writer.Object, It.IsAny<ODataSerializerContext>()))
                .Callback((object o, ODataWriter w, ODataSerializerContext context) =>
                    {
                        Assert.Same(context.EntitySet.Name, "Orders");
                        Assert.Same(context.SelectExpandClause, selectExpandNode.ExpandedNavigationProperties.Single().Value);
                    })
                .Verifiable();

            Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>();
            serializerProvider.Setup(p => p.GetODataPayloadSerializer(_model, _customer.Orders.GetType())).Returns(innerSerializer.Object);
            Mock<ODataEntityTypeSerializer> serializer = new Mock<ODataEntityTypeSerializer>(_serializer.EdmType, serializerProvider.Object);
            serializer.Setup(s => s.CreateSelectExpandNode(It.IsAny<EntityInstanceContext>())).Returns(selectExpandNode);
            serializer.CallBase = true;
            _writeContext.SelectExpandClause = selectExpandClause;

            // Act
            serializer.Object.WriteObjectInline(_customer, writer.Object, _writeContext);

            // Assert
            innerSerializer.Verify();
            // check that the context is rolled back
            Assert.Same(_writeContext.EntitySet.Name, "Customers");
            Assert.Same(_writeContext.SelectExpandClause, selectExpandClause);
        }
        public void ProjectAsWrapper_Element_ProjectedValueContains_KeyPropertiesEvenIfNotPresentInSelectClause(string select)
        {
            // Arrange
            Customer customer = new Customer { ID = 42, FirstName = "OData" };
            SelectExpandClause selectExpand =
                new ODataUriParser(_model.Model, serviceRoot: null).ParseSelectAndExpand(select, null, _model.Customer, _model.Customers);
            Expression source = Expression.Constant(customer);

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

            // Assert
            SelectExpandWrapper<Customer> customerWrapper = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper<Customer>;
            Assert.Equal(customer.ID, customerWrapper.Container.ToDictionary()["ID"]);
        }
        public void ProjectAsWrapper_Element_ProjectedValueContains_SelectedStructuralProperties()
        {
            // Arrange
            Customer customer = new Customer { Name = "OData" };
            SelectExpandClause selectExpand = new ODataUriParser(_model.Model, serviceRoot: null).ParseSelectAndExpand("Name,Orders", "Orders", _model.Customer, _model.Customers);
            Expression source = Expression.Constant(customer);

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

            // Assert
            SelectExpandWrapper<Customer> customerWrapper = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper<Customer>;
            Assert.Equal(customer.Name, customerWrapper.Container.ToDictionary()["Name"]);
        }
        public void ProjectAsWrapper_Element_ProjectedValueDoesNotContainInstance_IfSelectionIsPartial()
        {
            // Arrange
            Customer customer = new Customer();
            SelectExpandClause selectExpand = new ODataUriParser(_model.Model, serviceRoot: null).ParseSelectAndExpand("ID,Orders", "Orders", _model.Customer, _model.Customers);
            Expression source = Expression.Constant(customer);

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

            // Assert
            Assert.Equal(ExpressionType.MemberInit, projection.NodeType);
            Assert.Empty((projection as MemberInitExpression).Bindings.Where(p => p.Member.Name == "Instance"));
            SelectExpandWrapper<Customer> customerWrapper = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper<Customer>;
            Assert.Null(customerWrapper.Instance);
        }
Example #12
0
        public void ProjectAsWrapper_ProjectedValueContainsConcurrencyProperties_EvenIfNotPresentInSelectClause(string select)
        {
            // Arrange
            Customer customer = new Customer { ID = 42, City = "any" };
            SelectExpandClause selectExpand = new ODataUriParser(_model.Model, serviceRoot: null)
                .ParseSelectAndExpand(select, null, _model.Customer, _model.Customers);
            Expression source = Expression.Constant(customer);

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

            // Assert
            SelectExpandWrapper<Customer> customerWrapper = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper<Customer>;
            Assert.Equal(customer.City, customerWrapper.Container.ToDictionary(new IdentityPropertyMapper())["City"]);
        }