// Disallow the 'desc' parameter for $orderby option.
 public override void Validate(OrderByQueryOption orderByOption,
                                 ODataValidationSettings validationSettings)
 {
     if (orderByOption.OrderByNodes.Any(
             node => node.Direction == OrderByDirection.Descending))
     {
         throw new ODataException("The 'desc' option is not supported.");
     }
     base.Validate(orderByOption, validationSettings);
 }
            public override void ValidateSingleValuePropertyAccessNode(SingleValuePropertyAccessNode propertyAccessNode, ODataValidationSettings settings)
            {
                // Validate if we are accessing some sensitive property of Order, such as Quantity
                if (propertyAccessNode.Property.Name == "Quantity")
                {
                    throw new ODataException("Filter with Quantity is not allowed.");
                }

                base.ValidateSingleValuePropertyAccessNode(propertyAccessNode, settings);
            }
        public void AllowedOrderByProperties_Property_RoundTrips()
        {
            ODataValidationSettings settings = new ODataValidationSettings();
            Assert.NotNull(settings.AllowedOrderByProperties);
            Assert.Equal(0, settings.AllowedOrderByProperties.Count);

            settings.AllowedOrderByProperties.Add("Id");
            settings.AllowedOrderByProperties.Add("Name");

            Assert.Equal(2, settings.AllowedOrderByProperties.Count);
            Assert.Equal("Id", settings.AllowedOrderByProperties[0]);
            Assert.Equal("Name", settings.AllowedOrderByProperties[1]);
        }
        public void Ctor_Initializes_All_Properties()
        {
            // Arrange & Act
            ODataValidationSettings querySettings = new ODataValidationSettings();

            // Assert
            Assert.Equal(AllowedArithmeticOperators.All, querySettings.AllowedArithmeticOperators);
            Assert.Equal(AllowedFunctions.AllFunctions, querySettings.AllowedFunctions);
            Assert.Equal(AllowedLogicalOperators.All, querySettings.AllowedLogicalOperators);
            Assert.Equal(0, querySettings.AllowedOrderByProperties.Count);
            Assert.Equal(AllowedQueryOptions.Supported, querySettings.AllowedQueryOptions);
            Assert.Equal(1, querySettings.MaxAnyAllExpressionDepth);
            Assert.Equal(100, querySettings.MaxNodeCount);
            Assert.Null(querySettings.MaxSkip);
            Assert.Null(querySettings.MaxTop);
        }
        public async Task<HttpResponseMessage> Get(string id, ODataQueryOptions<UserInfo> options)
        {
            await _watchProjectService.CheckProjectAsync(id, UserId);

            var validationSettings = new ODataValidationSettings
            {
                MaxTop = 100,
                AllowedArithmeticOperators = AllowedArithmeticOperators.None,
                AllowedFunctions = AllowedFunctions.None,
                AllowedLogicalOperators = AllowedLogicalOperators.None,
                AllowedQueryOptions = AllowedQueryOptions.Skip | AllowedQueryOptions.Top
            };

            // Validating OData
            try
            {
                options.Validate(validationSettings);
            }
            catch (Exception)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }

            // Parsing filter parameters
            DataQueryOptions filter;
            try
            {
                filter = _mapper.Map<ODataQueryOptions, DataQueryOptions>(options);
            }
            catch (AutoMapperMappingException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }

            // Retrieving projects
            IEnumerable<UserInfo> users;
            try
            {
                users = await _projectAbuseService.GetProjectReportersSequenceAsync(id, filter);
            }
            catch (NotSupportedException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.BadRequest));
            }

            return Request.CreateResponse(HttpStatusCode.OK, users);
        }
        // Note this can be done through Queryable attribute as well
        public IQueryable<Order> Get(ODataQueryOptions queryOptions)
        {
            // Register a custom FilterByValidator to disallow custom logic in the filter query
            if (queryOptions.Filter != null)
            {
                queryOptions.Filter.Validator = new RestrictiveFilterByQueryValidator();
            }

            // Validate the query, we only allow order by Id property and 
            // we only allow maximum Top query value to be 9
            ODataValidationSettings settings = new ODataValidationSettings(){ MaxTop = 9 };
            settings.AllowedOrderByProperties.Add("Id");
            queryOptions.Validate(settings);

            // Apply the query
            return queryOptions.ApplyTo(OrderList.AsQueryable()) as IQueryable<Order>;
        }
        public async Task<HttpResponseMessage> GetWeek(ODataQueryOptions<TrendingWatch> options)
        {
            var validationSettings = new ODataValidationSettings
            {
                MaxTop = 100,
                AllowedArithmeticOperators = AllowedArithmeticOperators.None,
                AllowedFunctions = AllowedFunctions.None,
                AllowedLogicalOperators = AllowedLogicalOperators.Equal | AllowedLogicalOperators.And,
                AllowedQueryOptions = AllowedQueryOptions.Filter | AllowedQueryOptions.Skip | AllowedQueryOptions.Top
            };

            // Validating OData
            try
            {
                options.Validate(validationSettings);
            }
            catch (Exception)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }

            // Parsing filter parameters
            DataQueryOptions filter;
            try
            {
                filter = _mapper.Map<ODataQueryOptions, DataQueryOptions>(options);
            }
            catch (AutoMapperMappingException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }

            // Retrieving projects
            IEnumerable<TrendingWatch> watchProjects;
            try
            {
                watchProjects = await _viewsService.GetWeeklyTrendsSequenceAsync(filter);
            }
            catch (NotSupportedException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.BadRequest));
            }

            return Request.CreateResponse(HttpStatusCode.OK, watchProjects);
        }
        public async Task<HttpResponseMessage> Get(ODataQueryOptions<ExampleProject> options)
        {
            var validationSettings = new ODataValidationSettings
            {
                MaxTop = 100,
                AllowedArithmeticOperators = AllowedArithmeticOperators.None,
                AllowedFunctions = AllowedFunctions.None,
                AllowedLogicalOperators = AllowedLogicalOperators.None,
                AllowedQueryOptions = AllowedQueryOptions.Skip | AllowedQueryOptions.Top | AllowedQueryOptions.OrderBy
            };

            // Validating OData
            try
            {
                options.Validate(validationSettings);
            }
            catch (Exception)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }

            // Parsing filter parameters
            DataQueryOptions filter;
            try
            {
                filter = _mapper.Map<ODataQueryOptions, DataQueryOptions>(options);
            }
            catch (AutoMapperMappingException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }

            // Retrieving projects
            var projects = await _exampleProjectService.GetSequenceAsync(filter);

            return Request.CreateResponse(HttpStatusCode.OK, projects);
        }
 /// <summary>
 /// Enables a controller action to support OData query parameters.
 /// </summary>
 public QueryableAttribute()
 {
     EnsureStableOrdering = true;
     _validationSettings = new ODataValidationSettings();
 }
        public async Task<HttpResponseMessage> Get(ODataQueryOptions<Watch> options)
        {
            var validationSettings = new ODataValidationSettings
            {
                MaxTop = 100,
                AllowedArithmeticOperators = AllowedArithmeticOperators.None,
                AllowedFunctions = AllowedFunctions.None,
                AllowedLogicalOperators =
                    AllowedLogicalOperators.Equal | AllowedLogicalOperators.And | AllowedLogicalOperators.GreaterThan | AllowedLogicalOperators.GreaterThanOrEqual | AllowedLogicalOperators.LessThan |
                    AllowedLogicalOperators.LessThanOrEqual,
                AllowedQueryOptions = AllowedQueryOptions.Filter | AllowedQueryOptions.OrderBy |
                                      AllowedQueryOptions.Skip | AllowedQueryOptions.Top | AllowedQueryOptions.InlineCount
            };

            validationSettings.AllowedOrderByProperties.Add("Name");
            validationSettings.AllowedOrderByProperties.Add("Created");
            validationSettings.AllowedOrderByProperties.Add("HitsCount");


            // Validating OData
            try
            {
                options.Validate(validationSettings);
            }
            catch (Exception)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }


            // Parsing filter parameters
            DataQueryOptions filter;
            try
            {
                filter = _mapper.Map<ODataQueryOptions, DataQueryOptions>(options);
            }
            catch (AutoMapperMappingException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }


            // Special instructions for UserId filtering
            DataFilterRule userIdFilter = filter.Filters.FirstOrDefault(f => string.Compare(f.Name, NameOfHelper.PropertyName<Watch>(x => x.UserId),
                StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal);
            if (userIdFilter == null || userIdFilter.Value == null)
            {
                // For backward compatibility we treats not specified or empty UserId as current user
                if (string.IsNullOrEmpty(UserId))
                {
                    throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, ResponseMessages.UnathorizedRequest));
                }

                if (userIdFilter == null)
                {
                    userIdFilter = new DataFilterRule { Name = NameOfHelper.PropertyName<Watch>(x => x.UserId), Type = DataFilterTypes.Equal, Value = UserId };
                    filter.Filters.Add(userIdFilter);
                }
                else
                {
                    userIdFilter.Value = UserId;
                }
            }
            else if (string.Compare(userIdFilter.Value.ToString(), UserIdAllConstant, StringComparison.OrdinalIgnoreCase) == 0)
            {
                // special constant $all means not filtering by UserId
                userIdFilter.Value = null;
            }


            // Retrieving projects
            DataResult<Watch> watchProjects;
            try
            {
                watchProjects = await _watchProjectRepository.GetSequenceAsync(filter, UserId);
            }
            catch (NotSupportedException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.BadRequest));
            }

            if (filter.Count)
            {
                var pageResult = new PageResult<Watch>(watchProjects.Results, null, watchProjects.Count);
                return Request.CreateResponse(HttpStatusCode.OK, pageResult);
            }

            return Request.CreateResponse(HttpStatusCode.OK, watchProjects.Results);
        }
        public async Task<HttpResponseMessage> Get(string id, ODataQueryOptions<TrackingStatPerUrl> options)
        {
            var validationSettings = new ODataValidationSettings
            {
                MaxTop = 100,
                AllowedArithmeticOperators = AllowedArithmeticOperators.None,
                AllowedFunctions = AllowedFunctions.None,
                AllowedLogicalOperators =
                    AllowedLogicalOperators.Equal | AllowedLogicalOperators.And,
                AllowedQueryOptions =
                    AllowedQueryOptions.Filter | AllowedQueryOptions.OrderBy | AllowedQueryOptions.Skip | AllowedQueryOptions.Top | AllowedQueryOptions.InlineCount
            };

            // Validating query options
            try
            {
                options.Validate(validationSettings);
            }
            catch (Exception)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }


            // Parsing filter parameters
            DataQueryOptions filter;
            try
            {
                filter = _mapper.Map<ODataQueryOptions, DataQueryOptions>(options);
            }
            catch (AutoMapperMappingException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }

            // Get company for user
            DomainCompany company = await _companyService.FindByUserAsync(UserId);

            // Find subscription
            CompanySubscription subscription = company.Subscriptions.FirstOrDefault(s => s.Id == id);
            if (subscription == null)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, ResponseMessages.ResourceNotFound));
            }


            // Get stats
            DataResult<DomainTrackingStatPerUrl> stats;
            try
            {
                stats = await _urlTrackingStatService.GetStatsPerUrlAsync(id, filter);
            }
            catch (NotSupportedException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.BadRequest));
            }
            catch (ArgumentException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.BadRequest));
            }

            IEnumerable<TrackingStatPerUrl> results = stats.Results.Select(r => _mapper.Map<DomainTrackingStatPerUrl, TrackingStatPerUrl>(r));

            if (filter.Count)
            {
                var pageResult = new PageResult<TrackingStatPerUrl>(results, null, stats.Count);
                return Request.CreateResponse(HttpStatusCode.OK, pageResult);
            }

            return Request.CreateResponse(HttpStatusCode.OK, results);
        }
 public void VerifyValidateOptions(ODataValidationSettings settings, string query, bool success)
 {
     var response = this.Client.PostAsync(
         this.BaseAddress + "/api/ValidatorTests/ValidateOptions?" + query,
         new ObjectContent<ODataValidationSettings>(settings, new JsonMediaTypeFormatter())).Result;
     if (success)
     {
         response.EnsureSuccessStatusCode();
     }
     else
     {
         Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
     }
 }
        public PageResult<Product> GetProducts(ODataQueryOptions<Product> options)
        {
            var settings = new ODataQuerySettings()
            {
                PageSize = 1
            };

            if (options.OrderBy != null)
            {
                options.OrderBy.Validator = new MyOrderByValidator();
            }

            var settingsVal = new ODataValidationSettings()
            {
                // Initialize settings as needed.
                AllowedFunctions = AllowedFunctions.AllMathFunctions
            };
            // Validate
            options.Validate(settingsVal);

            IQueryable results = options.ApplyTo(Repository.GetAll().Select(AsProductTo), settings);

            return new PageResult<Product>(
                results as IEnumerable<Product>,
                Request.GetNextPageLink(),
                Request.GetInlineCount());
        }
        public void Validate_ThrowsValidationErrors_ForOrderBy()
        {
            // Arrange
            var model = new ODataModelBuilder().Add_Customer_EntityType().GetEdmModel();

            var message = new HttpRequestMessage(
                HttpMethod.Get,
                new Uri("http://server/service/Customers?$orderby=CustomerId,Name")
            );

            var options = new ODataQueryOptions(new ODataQueryContext(model, typeof(Customer)), message);
            ODataValidationSettings validationSettings = new ODataValidationSettings { MaxOrderByNodeCount = 1 };

            // Act & Assert
            Assert.Throws<ODataException>(() => options.Validate(validationSettings),
                "The number of clauses in $orderby query option exceeded the maximum number allowed. The maximum number of $orderby clauses allowed is 1.");
        }
        public void CanTurnOffValidationForSkip()
        {
            // Arrange
            ODataValidationSettings settings = new ODataValidationSettings()
            {
                MaxSkip = 10
            };
            SkipQueryOption option = new SkipQueryOption("11", ValidationTestHelper.CreateCustomerContext());

            // Act and Assert
            Assert.Throws<ODataException>(() =>
                option.Validate(settings),
                "The limit of '10' for Skip query has been exceeded. The value from the incoming request is '11'.");
            option.Validator = null;
            Assert.DoesNotThrow(() => option.Validate(settings));
        }
        public override void ValidateConstantNode(ConstantNode constantNode, ODataValidationSettings settings)
        {
            // Validate that client did not send a big constant in the query
            if (Convert.ToInt32(constantNode.Value) > 100)
            {
                throw new ODataException("Any constant that is more than 100 is not allowed.");
            }

            base.ValidateConstantNode(constantNode, settings);
        }
        public async Task<IEnumerable<TrackingStatPerDate>> Get(string id, [FromUri] ClientSubscriptionStatUrlModel model, ODataQueryOptions<TrackingStatPerDate> options)
        {
            var validationSettings = new ODataValidationSettings
            {
                AllowedArithmeticOperators = AllowedArithmeticOperators.None,
                AllowedFunctions = AllowedFunctions.None,
                AllowedLogicalOperators =
                    AllowedLogicalOperators.Equal | AllowedLogicalOperators.LessThan | AllowedLogicalOperators.LessThanOrEqual | AllowedLogicalOperators.GreaterThan |
                    AllowedLogicalOperators.GreaterThanOrEqual | AllowedLogicalOperators.And,
                AllowedQueryOptions = AllowedQueryOptions.Filter
            };

            // Validating query options
            try
            {
                options.Validate(validationSettings);
            }
            catch (Exception)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }


            // Parsing filter parameters
            DataQueryOptions filter;
            try
            {
                filter = _mapper.Map<ODataQueryOptions, DataQueryOptions>(options);
            }
            catch (AutoMapperMappingException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions));
            }


            // Get company for user
            DomainCompany company = await _companyService.FindBySubscriptionAsync(id);

            if (!company.Users.Contains(UserId))
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Forbidden, ResponseMessages.Forbidden));
            }

            // Find subscription
            CompanySubscription subscription = company.Subscriptions.FirstOrDefault(s => s.Id == id);
            if (subscription == null)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, ResponseMessages.ResourceNotFound));
            }

            // Get stats
            IEnumerable<DomainTrackingStatPerDate> stats;
            try
            {
                stats = await _urlTrackingStatService.GetStatsPerDateAsync(id, model.Url, filter);
            }
            catch (NotSupportedException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.BadRequest));
            }
            catch (ArgumentException)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.BadRequest));
            }

            IEnumerable<TrackingStatPerDate> results = stats.Select(r => _mapper.Map<DomainTrackingStatPerDate, TrackingStatPerDate>(r));
            return results;
        }
        public async Task<HttpResponseMessage> Get(string id, ODataQueryOptions<AdminProject> options)
        {
            // Checks whether user exists
            await _userService.GetAsync(id);

            var validationSettings = new ODataValidationSettings
            {
                MaxTop = 100,
                AllowedArithmeticOperators = AllowedArithmeticOperators.None,
                AllowedFunctions = AllowedFunctions.None,
                AllowedLogicalOperators =
                    AllowedLogicalOperators.Equal | AllowedLogicalOperators.LessThan | AllowedLogicalOperators.LessThanOrEqual | AllowedLogicalOperators.GreaterThan |
                    AllowedLogicalOperators.GreaterThanOrEqual | AllowedLogicalOperators.And,
                AllowedQueryOptions = AllowedQueryOptions.Filter | AllowedQueryOptions.OrderBy | AllowedQueryOptions.Skip | AllowedQueryOptions.Top | AllowedQueryOptions.InlineCount
            };

            validationSettings.AllowedOrderByProperties.Add("Name");
            validationSettings.AllowedOrderByProperties.Add("Created");
            validationSettings.AllowedOrderByProperties.Add("ProductType");

            try
            {
                options.Validate(validationSettings);
            }
            catch (Exception)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions);
            }


            // retrieving projects
            DataResult<Task<DomainProjectForAdmin>> result;
            IEnumerable<Task<AdminProject>> projectTasks;
            DataQueryOptions filter;

            // parsing filter parameters
            try
            {
                filter = _mapper.Map<ODataQueryOptions, DataQueryOptions>(options);
            }
            catch (AutoMapperMappingException)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions);
            }


            filter.Filters.Add(new DataFilterRule
            {
                Name = NameOfHelper.PropertyName<DomainProjectForAdmin>(x => x.UserId),
                Type = DataFilterTypes.Equal,
                Value = id
            });


            try
            {
                // filtering projects
                result = await _adminProjectService.GetAsyncSequenceAsync(filter);
                projectTasks = result.Results.Select(t => t.ContinueWith(u => _mapper.Map<DomainProjectForAdmin, AdminProject>(u.Result)));
            }
            catch (NotSupportedException)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.BadRequest);
            }

            // loading and shaping all projects
            List<AdminProject> projects = (await Task.WhenAll(projectTasks)).ToList();

            if (filter.Count)
            {
                var pageResult = new PageResult<AdminProject>(projects, null, result.Count);
                return Request.CreateResponse(HttpStatusCode.OK, pageResult);
            }

            return Request.CreateResponse(HttpStatusCode.OK, projects);
        }
        public async Task<HttpResponseMessage> Get(ODataQueryOptions<AdminProject> options)
        {
            var validationSettings = new ODataValidationSettings
            {
                MaxTop = 100,
                AllowedArithmeticOperators = AllowedArithmeticOperators.None,
                AllowedFunctions = AllowedFunctions.None,
                AllowedLogicalOperators =
                    AllowedLogicalOperators.Equal | AllowedLogicalOperators.LessThan | AllowedLogicalOperators.LessThanOrEqual | AllowedLogicalOperators.GreaterThan |
                    AllowedLogicalOperators.GreaterThanOrEqual | AllowedLogicalOperators.And,
                AllowedQueryOptions =
                    AllowedQueryOptions.Filter | AllowedQueryOptions.OrderBy | AllowedQueryOptions.Skip | AllowedQueryOptions.Top | AllowedQueryOptions.Format | AllowedQueryOptions.InlineCount
            };

            validationSettings.AllowedOrderByProperties.Add("Name");
            validationSettings.AllowedOrderByProperties.Add("Created");
            validationSettings.AllowedOrderByProperties.Add("ProductType");

            try
            {
                options.Validate(validationSettings);
            }
            catch (Exception)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions);
            }


            // Determine media formatter
            IContentNegotiator negotiator = Configuration.Services.GetContentNegotiator();
            ContentNegotiationResult negotiationResult = negotiator.Negotiate(typeof (AdminProject), Request, Configuration.Formatters);
            if (negotiationResult == null)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, ResponseMessages.NotAcceptable);
            }

            // Parsing filter parameters
            DataQueryOptions filter;
            try
            {
                filter = _mapper.Map<ODataQueryOptions, DataQueryOptions>(options);
            }
            catch (AutoMapperMappingException)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.InvalidQueryOptions);
            }


            // CSV
            if (negotiationResult.Formatter is ProjectForAdminCsvFormatter)
            {
                // get csv service
                ICsvPublishService csvService = _csvPublishServiceFactory.GetService<AdminProject>();

                // send the link to the future csv file
                string fileName = string.Format("{0}.csv", Guid.NewGuid());
                Uri fileUri = csvService.GetAccessCsvUri(fileName);
                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Accepted);
                response.Headers.Location = fileUri;

                // disable paging
                filter.Take = null;

                // start csv publishing in background thread
                Task.Run(() => csvService.PublishAsync(filter, fileName, new CancellationTokenSource())).NoWarning();

                return response;
            }


            // Filtering projects
            DataResult<Task<DomainProjectForAdmin>> result;
            IEnumerable<Task<AdminProject>> projectTasks;
            try
            {
                result = await _adminProjectService.GetAsyncSequenceAsync(filter);
                projectTasks = result.Results.Select(t => t.ContinueWith(u => _mapper.Map<DomainProjectForAdmin, AdminProject>(u.Result)));
            }
            catch (NotSupportedException)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ResponseMessages.BadRequest);
            }


            // Loading and shaping all projects
            List<AdminProject> projects = (await Task.WhenAll(projectTasks)).ToList();

            if (filter.Count)
            {
                var pageResult = new PageResult<AdminProject>(projects, null, result.Count);
                return Request.CreateResponse(HttpStatusCode.OK, pageResult);
            }

            return Request.CreateResponse(HttpStatusCode.OK, projects);
        }
        /// <summary>
        /// Validate the filter query based on the given <paramref name="validationSettings"/>. It throws an ODataException if validation failed.
        /// </summary>
        /// <param name="validationSettings">The <see cref="ODataValidationSettings"/> instance which contains all the validation settings.</param>
        public void Validate(ODataValidationSettings validationSettings)
        {
            if (validationSettings == null)
            {
                throw Error.ArgumentNull("validationSettings");
            }

            if (Validator != null)
            {
                Validator.Validate(this, validationSettings);
            }
        }
        public void CanTurnOffValidationForFilter()
        {
            ODataValidationSettings settings = new ODataValidationSettings() { AllowedFunctions = AllowedFunctions.AllDateTimeFunctions };
            ODataQueryContext context = ValidationTestHelper.CreateCustomerContext();
            FilterQueryOption option = new FilterQueryOption("substring(Name,8,1) eq '7'", context);

            Assert.Throws<ODataException>(() =>
                option.Validate(settings),
                "Function 'substring' is not allowed. To allow it, set the 'AllowedFunctions' property on QueryableAttribute or QueryValidationSettings.");

            option.Validator = null;
            Assert.DoesNotThrow(() => option.Validate(settings));
        }
        public void CanTurnOffAllValidation()
        {
            // Arrange
            HttpRequestMessage message = new HttpRequestMessage(
                HttpMethod.Get,
                new Uri("http://localhost/?$filter=Name eq 'abc'")
            );

            ODataQueryContext context = ValidationTestHelper.CreateCustomerContext();
            ODataQueryOptions option = new ODataQueryOptions(context, message);
            ODataValidationSettings settings = new ODataValidationSettings()
            {
                AllowedQueryOptions = AllowedQueryOptions.OrderBy
            };

            // Act & Assert
            Assert.Throws<ODataException>(() => option.Validate(settings),
                "Query option 'Filter' is not allowed. To allow it, set the 'AllowedQueryOptions' property on QueryableAttribute or QueryValidationSettings.");

            option.Validator = null;
            Assert.DoesNotThrow(() => option.Validate(settings));

        }
        public override void Validate(OrderByQueryOption option, ODataValidationSettings validationSettings)
        {
            // validate the orderby is executed in a way that one can order either by Id or by Name, but not both
            if (option.OrderByNodes.Count > 1)
            {
                throw new ODataException("Order by more than one property is not allowed.");
            }

            base.Validate(option, validationSettings);
        }
 public IQueryable<ValidatorTests_Todo> ValidateWithCustomValidator(ODataQueryOptions options)
 {
     if (options.Filter != null)
     {
         options.Filter.Validator = new CustomFilterValidator();
     }
     try
     {
         ODataValidationSettings settings = new ODataValidationSettings();
         options.Validate(settings);
     }
     catch (ODataException ex)
     {
         throw new HttpResponseException(this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex));
     }
     return options.ApplyTo(todoes.AsQueryable()) as IQueryable<ValidatorTests_Todo>;
 }
 /// <summary>
 /// Enables a controller action to support OData query parameters.
 /// </summary>
 public QueryableAttribute()
 {
     _validationSettings = new ODataValidationSettings();
     _querySettings = new ODataQuerySettings();
 }
 public override void ValidateSingleValuePropertyAccessNode(Microsoft.Data.OData.Query.SemanticAst.SingleValuePropertyAccessNode propertyAccessNode, ODataValidationSettings settings)
 {
     if (propertyAccessNode.Property.Name == "ID")
     {
         visited = true;
     }
     base.ValidateSingleValuePropertyAccessNode(propertyAccessNode, settings);
 }
        public void CanTurnOffValidationForOrderBy()
        {
            // Arrange
            ODataQueryContext context = ValidationTestHelper.CreateCustomerContext();

            OrderByQueryOption option = new OrderByQueryOption("Name", context);
            ODataValidationSettings settings = new ODataValidationSettings();
            settings.AllowedOrderByProperties.Add("Id");

            // Act & Assert
            Assert.Throws<ODataException>(() => option.Validate(settings),
                "Order by 'Name' is not allowed. To allow it, set the 'AllowedOrderByProperties' property on EnableQueryAttribute or QueryValidationSettings.");

            option.Validator = null;
            Assert.DoesNotThrow(() => option.Validate(settings));
        }
        public override void Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings)
        {
            base.Validate(filterQueryOption, settings);

            if (!visited)
            { 
                throw new ODataException("$filter query must contain ID property");
            }
        }