public void PageResult_SerializesToXml()
        {
            PageResult<string> result = new PageResult<string>(new string[] { "a", "b", "c" }, new Uri("http://localhost/NextPage"), 3);
            MemoryStream ms = new MemoryStream();

            new XmlMediaTypeFormatter().WriteToStreamAsync(typeof(PageResult<string>), result, ms, content: null, transportContext: null).Wait();

            ms.Position = 0;
            Assert.Equal(
                @"<PageResultOfstring xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.datacontract.org/2004/07/System.Web.Http.OData""><Count>3</Count><NextPageLink>http://localhost/NextPage</NextPageLink><Items xmlns:d2p1=""http://schemas.microsoft.com/2003/10/Serialization/Arrays""><d2p1:string>a</d2p1:string><d2p1:string>b</d2p1:string><d2p1:string>c</d2p1:string></Items></PageResultOfstring>",
                new StreamReader(ms).ReadToEnd());
        }
        public void PageResult_SerializesToJson()
        {
            PageResult<string> result = new PageResult<string>(new string[] { "a", "b", "c" }, new Uri("http://localhost/NextPage"), 3);
            MemoryStream ms = new MemoryStream();

            new JsonMediaTypeFormatter().WriteToStreamAsync(typeof(PageResult<string>), result, ms, content: null, transportContext: null).Wait();

            ms.Position = 0;
            Assert.Equal(
                @"{""Items"":[""a"",""b"",""c""],""NextPageLink"":""http://localhost/NextPage"",""Count"":3}",
                new StreamReader(ms).ReadToEnd());
        }
        public PageResult<Customer> Get(ODataQueryOptions<Customer> options)
        {
            Guid VALID_TENANT_ID = Guid.Parse("7b6791d5-8658-44e5-86bc-8181735d0bf7");

            IQueryable query = dbContext.Customers.Where(c => c.Tenant_Id == VALID_TENANT_ID);

            ODataQuerySettings odataSettings = new ODataQuerySettings();

            if (options.Filter != null)
            {
                // set validator that restricts client's filtering
                options.Filter.Validator = new QuoteQueryValidator();
                options.Validate(new ODataValidationSettings());

                query = options.Filter.ApplyTo(query, odataSettings);
            }

            // get the total count
            IQueryable<Customer> custQuery = query as IQueryable<Customer>;
            long totalCount = custQuery.LongCount();

            if (options.OrderBy != null)
            {
                query = options.OrderBy.ApplyTo(query, odataSettings);
            }

            if (options.Skip != null)
                query = options.Skip.ApplyTo(query, odataSettings);

            if (options.Top != null)
                query = options.Top.ApplyTo(query, odataSettings);

               // if (options.SelectExpand != null)
             //   query = options.SelectExpand.ApplyTo(query, odataSettings);

            //var resultList = new List<Customer>(query);

            var retValue = new PageResult<Customer>(
                    query as IEnumerable<Customer>,
                    Request.GetNextPageLink(),
                    totalCount);

            return retValue;
        }
        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 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);
        }
        public IHttpActionResult GetOdata(ODataQueryOptions<CandidateDto> options)
        {
            try
            {
                var query = _candidateService.Query().MapToDto();

                IQueryable results = options.ApplyTo(query.OrderByDescending(c => c.AddDate));
                var result = new PageResult<CandidateDto>(
                    results as IEnumerable<CandidateDto>,
                    Request.ODataProperties().NextLink,
                    Request.ODataProperties().TotalCount);
                return Ok(result);
            }
            catch (Exception e)
            {

                return BadRequest(e.Message);
            }
        }
        public HttpResponseMessage GetLongListOdata(ODataQueryOptions<CandidateLongListDto> options, int vid)
        {
            try
            {
                IQueryable candidates =
                    options.ApplyTo(_candidateService.GetLongList(vid).AsQueryable());

                if (candidates == null)
                {
                    return Request.CreateResponse(HttpStatusCode.BadRequest, "Vacancy has no candidates!");
                }

                var filteredCardidates = new PageResult<CandidateLongListDto>(
                        candidates as IEnumerable<CandidateLongListDto>,
                        Request.ODataProperties().NextLink,
                        Request.ODataProperties().TotalCount);
                filteredCardidates.Items.ForEach(x => x.PoolColors = _candidateService.GetColors(x.Id));

                return Request.CreateResponse(HttpStatusCode.OK, filteredCardidates);
            }
            catch (Exception ex)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message);
            }
        }