Example #1
0
        internal IQueryable ApplyPaging(IQueryable result, ODataQuerySettings querySettings)
        {
            int pageSize = -1;
            if (querySettings.PageSize.HasValue)
            {
                pageSize = querySettings.PageSize.Value;
            }
            else if (querySettings.ModelBoundPageSize.HasValue)
            {
                pageSize = querySettings.ModelBoundPageSize.Value;
            }

            int preferredPageSize = -1;
            if (RequestPreferenceHelpers.RequestPrefersMaxPageSize(Request.Headers, out preferredPageSize))
            {
                pageSize = Math.Min(pageSize, preferredPageSize);
            }

            ODataFeature odataFeature = Request.ODataFeature() as ODataFeature;
            if (pageSize > 0)
            {
                bool resultsLimited;
                result = LimitResults(result, pageSize, querySettings.EnableConstantParameterization, out resultsLimited);
                if (resultsLimited && Request.GetEncodedUrl() != null &&
                    odataFeature.NextLink == null)
                {
                    odataFeature.PageSize = pageSize;
                }
            }

            odataFeature.QueryOptions = this;

            return result;
        }
Example #2
0
        internal IQueryable ApplyPaging(IQueryable result, ODataQuerySettings querySettings)
        {
            if (!querySettings.PostponePaging)
            {
                int pageSize = -1;
                if (querySettings.PageSize.HasValue)
                {
                    pageSize = querySettings.PageSize.Value;
                }
                else if (querySettings.ModelBoundPageSize.HasValue)
                {
                    pageSize = querySettings.ModelBoundPageSize.Value;
                }

                int preferredPageSize = -1;
                if (RequestPreferenceHelpers.RequestPrefersMaxPageSize(InternalRequest.Headers, out preferredPageSize))
                {
                    pageSize = Math.Min(pageSize, preferredPageSize);
                }

                if (pageSize > 0)
                {
                    bool resultsLimited;
                    result = LimitResults(result, pageSize, querySettings.EnableConstantParameterization, out resultsLimited);
                    if (resultsLimited && InternalRequest.RequestUri != null &&
                        InternalRequest.Context.NextLink == null)
                    {
                        InternalRequest.Context.PageSize = pageSize;
                    }
                }
            }
            InternalRequest.Context.QueryOptions = this;

            return(result);
        }
Example #3
0
        internal static IODataResponseMessage PrepareResponseMessage(IWebApiRequestMessage internalRequest, IWebApiHeaders internalRequestHeaders, Func <IServiceProvider, ODataMessageWrapper> getODataMessageWrapper)
        {
            string preferHeader     = RequestPreferenceHelpers.GetRequestPreferHeader(internalRequestHeaders);
            string annotationFilter = null;
            string omitValues       = null;
            int?   maxPageSize      = null;

            if (!String.IsNullOrEmpty(preferHeader))
            {
                ODataMessageWrapper messageWrapper = getODataMessageWrapper(null);
                messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader);
                annotationFilter = messageWrapper.PreferHeader().AnnotationFilter;
                omitValues       = messageWrapper.PreferHeader().OmitValues;
                maxPageSize      = messageWrapper.PreferHeader().MaxPageSize;
            }

            IODataResponseMessage responseMessage = getODataMessageWrapper(internalRequest.RequestContainer);

            if (annotationFilter != null)
            {
                responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter;
            }

            if (omitValues != null)
            {
                responseMessage.PreferenceAppliedHeader().OmitValues = omitValues;
            }

            if (maxPageSize != null)
            {
                responseMessage.PreferenceAppliedHeader().MaxPageSize = maxPageSize;
            }

            return(responseMessage);
        }
Example #4
0
        public void RequestPrefersMaxPageSize_ReturnsFalse_WithPreferHeader()
        {
            // Arrange
            HeaderDictionary headers = new HeaderDictionary();

            // Act & Assert
            Assert.False(RequestPreferenceHelpers.RequestPrefersMaxPageSize(headers, out _));
        }
Example #5
0
 internal IHttpActionResult GetInnerActionResult()
 {
     if (RequestPreferenceHelpers.RequestPrefersReturnNoContent(Request))
     {
         return(new StatusCodeResult(HttpStatusCode.NoContent, Request));
     }
     else
     {
         return(_innerResult);
     }
 }
 internal IHttpActionResult GetInnerActionResult()
 {
     if (RequestPreferenceHelpers.RequestPrefersReturnContent(new WebApiRequestHeaders(_innerResult.Request.Headers)))
     {
         return(_innerResult);
     }
     else
     {
         return(new StatusCodeResult(HttpStatusCode.NoContent, _innerResult.Request));
     }
 }
        internal IHttpActionResult GetInnerActionResult(HttpRequestMessage request)
        {
            WebApiRequestHeaders headers = new WebApiRequestHeaders(request.Headers);

            if (RequestPreferenceHelpers.RequestPrefersReturnNoContent(headers))
            {
                return(new StatusCodeResult(HttpStatusCode.NoContent, request));
            }
            else
            {
                return(_innerResult);
            }
        }
        /// <summary>
        /// Set ContinueOnError based on the request and headers.
        /// </summary>
        /// <param name="header">The request header.</param>
        /// <param name="enableContinueOnErrorHeader">Flag indicating if continue on error header is enabled.</param>
        internal void SetContinueOnError(IWebApiHeaders header, bool enableContinueOnErrorHeader)
        {
            string preferHeader = RequestPreferenceHelpers.GetRequestPreferHeader(header);

            if ((preferHeader != null && preferHeader.Contains(PreferenceContinueOnError)) || (!enableContinueOnErrorHeader))
            {
                ContinueOnError = true;
            }
            else
            {
                ContinueOnError = false;
            }
        }
Example #9
0
        public void RequestPrefersMaxPageSize_ReturnsPageSize_WithPreferValue(string preferValue)
        {
            // Arrange
            HeaderDictionary headers = new HeaderDictionary(
                new Dictionary <string, StringValues>(StringComparer.OrdinalIgnoreCase)
            {
                { "Prefer", preferValue }
            });

            // Act & Assert
            Assert.True(RequestPreferenceHelpers.RequestPrefersMaxPageSize(headers, out int pageSize));
            Assert.Equal(5, pageSize);
        }
Example #10
0
        internal IActionResult GetInnerActionResult(HttpRequest request)
        {
            if (RequestPreferenceHelpers.RequestPrefersReturnContent(new WebApiRequestHeaders(request.Headers)))
            {
                ObjectResult objectResult = new ObjectResult(_innerResult)
                {
                    StatusCode = StatusCodes.Status200OK
                };

                return(objectResult);
            }
            else
            {
                return(new StatusCodeResult((int)HttpStatusCode.NoContent));
            }
        }
Example #11
0
        /// <summary>
        /// Set ContinueOnError based on the request and headers.
        /// </summary>
        /// <param name="header">The request header.</param>
        /// <param name="enableContinueOnErrorHeader">Flag indicating if continue on error header is enabled.</param>
        internal void SetContinueOnError(IHeaderDictionary header, bool enableContinueOnErrorHeader)
        {
            string preferHeader = RequestPreferenceHelpers.GetRequestPreferHeader(header);

            if ((preferHeader != null &&
                 preferHeader.Contains(PreferenceContinueOnError, StringComparison.OrdinalIgnoreCase) &&
                 !preferHeader.Contains(PreferenceContinueOnErrorFalse, StringComparison.OrdinalIgnoreCase)) ||
                (!enableContinueOnErrorHeader))
            {
                ContinueOnError = true;
            }
            else
            {
                ContinueOnError = false;
            }
        }
        // internal just for unit test.
        internal IActionResult GetInnerActionResult(HttpRequest request)
        {
            if (RequestPreferenceHelpers.RequestPrefersReturnNoContent(request.Headers))
            {
                return(new StatusCodeResult((int)HttpStatusCode.NoContent));
            }
            else
            {
                ObjectResult objectResult = new ObjectResult(Entity)
                {
                    StatusCode = StatusCodes.Status201Created
                };

                return(objectResult);
            }
        }
Example #13
0
        /// <inheritdoc/>
        public override async Task <HttpResponseMessage> ProcessBatchAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            ValidateRequest(request);

            IList <ODataBatchRequestItem> subRequests = await ParseBatchRequestsAsync(request, cancellationToken);

            string preferHeader = RequestPreferenceHelpers.GetRequestPreferHeader(request);

            if ((preferHeader != null && preferHeader.Contains(PreferenceContinueOnError)) || (!request.GetConfiguration().HasEnabledContinueOnErrorHeader()))
            {
                ContinueOnError = true;
            }
            else
            {
                ContinueOnError = false;
            }

            try
            {
                IList <ODataBatchResponseItem> responses = await ExecuteRequestMessagesAsync(subRequests, cancellationToken);

                return(await CreateResponseMessageAsync(responses, request, cancellationToken));
            }
            finally
            {
                foreach (ODataBatchRequestItem subRequest in subRequests)
                {
                    request.RegisterForDispose(subRequest.GetResourcesForDisposal());
                    request.RegisterForDispose(subRequest);
                }
            }
        }
Example #14
0
        internal static object ReadFromStream(
#endif
            Type type,
            object defaultValue,
            IEdmModel model,
            ODataVersion version,
            Uri baseAddress,
            IWebApiRequestMessage internalRequest,
            Func <IODataRequestMessage> getODataRequestMessage,
            Func <IEdmTypeReference, ODataDeserializer> getEdmTypeDeserializer,
            Func <Type, ODataDeserializer> getODataPayloadDeserializer,
            Func <ODataDeserializerContext> getODataDeserializerContext,
            Action <IDisposable> registerForDisposeAction,
            Action <Exception> logErrorAction)
        {
            object result;

            IEdmTypeReference expectedPayloadType;
            ODataDeserializer deserializer = GetDeserializer(type, internalRequest.Context.Path, model, getEdmTypeDeserializer, getODataPayloadDeserializer, out expectedPayloadType);

            if (deserializer == null)
            {
                throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, typeof(ODataInputFormatterHelper).FullName);
            }

            try
            {
                ODataMessageReaderSettings oDataReaderSettings = internalRequest.ReaderSettings;
                oDataReaderSettings.BaseUri     = baseAddress;
                oDataReaderSettings.Validations = oDataReaderSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;
                oDataReaderSettings.Version     = version;

                IODataRequestMessage oDataRequestMessage = getODataRequestMessage();

                string preferHeader     = RequestPreferenceHelpers.GetRequestPreferHeader(internalRequest.Headers);
                string annotationFilter = null;
                if (!String.IsNullOrEmpty(preferHeader))
                {
                    oDataRequestMessage.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader);
                    annotationFilter = oDataRequestMessage.PreferHeader().AnnotationFilter;
                }

                if (annotationFilter != null)
                {
                    oDataReaderSettings.ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter(annotationFilter);
                }

                ODataMessageReader oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model);
                registerForDisposeAction(oDataMessageReader);

                ODataPath path = internalRequest.Context.Path;
                ODataDeserializerContext readContext = getODataDeserializerContext();
                readContext.Path            = path;
                readContext.Model           = model;
                readContext.ResourceType    = type;
                readContext.ResourceEdmType = expectedPayloadType;

#if NETCORE
                result = await deserializer.ReadAsync(oDataMessageReader, type, readContext);
#else
                result = deserializer.Read(oDataMessageReader, type, readContext);
#endif
            }
            catch (Exception e)
            {
                logErrorAction(e);
                result = defaultValue;
            }

            return(result);
        }
Example #15
0
        private void WriteToStream(Type type, object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)
        {
            IEdmModel model = Request.ODataProperties().Model;

            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
            }

            ODataSerializer serializer = GetSerializer(type, value, model, _serializerProvider);

            UrlHelper urlHelper = Request.GetUrlHelper() ?? new UrlHelper(Request);

            ODataPath            path = Request.ODataProperties().Path;
            IEdmNavigationSource targetNavigationSource = path == null ? null : path.NavigationSource;

            // serialize a response
            HttpConfiguration configuration = Request.GetConfiguration();

            if (configuration == null)
            {
                throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration);
            }

            string preferHeader     = RequestPreferenceHelpers.GetRequestPreferHeader(Request);
            string annotationFilter = null;

            if (!String.IsNullOrEmpty(preferHeader))
            {
                ODataMessageWrapper messageWrapper = new ODataMessageWrapper(writeStream, content.Headers);
                messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader);
                annotationFilter = messageWrapper.PreferHeader().AnnotationFilter;
            }

            IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream, content.Headers);

            if (annotationFilter != null)
            {
                responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter;
            }

            Uri baseAddress = GetBaseAddress(Request);
            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings(MessageWriterSettings)
            {
                PayloadBaseUri = baseAddress,
                Version        = _version,
            };

            string metadataLink = urlHelper.CreateODataLink(new MetadataPathSegment());

            if (metadataLink == null)
            {
                throw new SerializationException(SRResources.UnableToDetermineMetadataUrl);
            }

            writerSettings.ODataUri = new ODataUri
            {
                ServiceRoot = baseAddress,

                // TODO: 1604 Convert webapi.odata's ODataPath to ODL's ODataPath, or use ODL's ODataPath.
                SelectAndExpand = Request.ODataProperties().SelectExpandClause,
                Path            = (path == null || IsOperationPath(path)) ? null : path.ODLPath,
            };

            MediaTypeHeaderValue contentType = null;

            if (contentHeaders != null && contentHeaders.ContentType != null)
            {
                contentType = contentHeaders.ContentType;
            }

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model))
            {
                ODataSerializerContext writeContext = new ODataSerializerContext()
                {
                    Request          = Request,
                    RequestContext   = Request.GetRequestContext(),
                    Url              = urlHelper,
                    NavigationSource = targetNavigationSource,
                    Model            = model,
                    RootElementName  = GetRootElementName(path) ?? "root",
                    SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed,
                    Path               = path,
                    MetadataLevel      = ODataMediaTypes.GetMetadataLevel(contentType),
                    SelectExpandClause = Request.ODataProperties().SelectExpandClause
                };

                serializer.WriteObject(value, type, messageWriter, writeContext);
            }
        }
        internal static void WriteToStream(
            Type type,
            object value,
            IEdmModel model,
            ODataVersion version,
            Uri baseAddress,
            MediaTypeHeaderValue contentType,
            IWebApiUrlHelper internaUrlHelper,
            IWebApiRequestMessage internalRequest,
            IWebApiHeaders internalRequestHeaders,
            Func <IServiceProvider, ODataMessageWrapper> getODataMessageWrapper,
            Func <IEdmTypeReference, ODataSerializer> getEdmTypeSerializer,
            Func <Type, ODataSerializer> getODataPayloadSerializer,
            Func <ODataSerializerContext> getODataSerializerContext)
        {
            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
            }

            ODataSerializer serializer = GetSerializer(type, value, internalRequest, getEdmTypeSerializer, getODataPayloadSerializer);

            ODataPath            path = internalRequest.Context.Path;
            IEdmNavigationSource targetNavigationSource = path == null ? null : path.NavigationSource;

            // serialize a response
            string preferHeader     = RequestPreferenceHelpers.GetRequestPreferHeader(internalRequestHeaders);
            string annotationFilter = null;

            if (!String.IsNullOrEmpty(preferHeader))
            {
                ODataMessageWrapper messageWrapper = getODataMessageWrapper(null);
                messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader);
                annotationFilter = messageWrapper.PreferHeader().AnnotationFilter;
            }

            IODataResponseMessage responseMessage = getODataMessageWrapper(internalRequest.RequestContainer);

            if (annotationFilter != null)
            {
                responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter;
            }

            ODataMessageWriterSettings writerSettings = internalRequest.WriterSettings;

            writerSettings.BaseUri     = baseAddress;
            writerSettings.Version     = version;
            writerSettings.Validations = writerSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;

            string metadataLink = internaUrlHelper.CreateODataLink(MetadataSegment.Instance);

            if (metadataLink == null)
            {
                throw new SerializationException(SRResources.UnableToDetermineMetadataUrl);
            }

            //Set this variable if the SelectExpandClause is different from the processed clause on the Query options
            SelectExpandClause selectExpandDifferentFromQueryOptions = null;

            if (internalRequest.Context.QueryOptions != null && internalRequest.Context.QueryOptions.SelectExpand != null)
            {
                if (internalRequest.Context.QueryOptions.SelectExpand.ProcessedSelectExpandClause != internalRequest.Context.ProcessedSelectExpandClause)
                {
                    selectExpandDifferentFromQueryOptions = internalRequest.Context.ProcessedSelectExpandClause;
                }
            }
            else if (internalRequest.Context.ProcessedSelectExpandClause != null)
            {
                selectExpandDifferentFromQueryOptions = internalRequest.Context.ProcessedSelectExpandClause;
            }

            writerSettings.ODataUri = new ODataUri
            {
                ServiceRoot = baseAddress,

                SelectAndExpand = internalRequest.Context.ProcessedSelectExpandClause,
                Apply           = internalRequest.Context.ApplyClause,
                Path            = ConvertPath(path),
            };

            ODataMetadataLevel metadataLevel = ODataMetadataLevel.MinimalMetadata;

            if (contentType != null)
            {
                IEnumerable <KeyValuePair <string, string> > parameters =
                    contentType.Parameters.Select(val => new KeyValuePair <string, string>(val.Name, val.Value));
                metadataLevel = ODataMediaTypes.GetMetadataLevel(contentType.MediaType, parameters);
            }

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model))
            {
                ODataSerializerContext writeContext = getODataSerializerContext();
                writeContext.NavigationSource = targetNavigationSource;
                writeContext.Model            = model;
                writeContext.RootElementName  = GetRootElementName(path) ?? "root";
                writeContext.SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.ResourceSet;
                writeContext.Path          = path;
                writeContext.MetadataLevel = metadataLevel;
                writeContext.QueryOptions  = internalRequest.Context.QueryOptions;

                //Set the SelectExpandClause on the context if it was explicitly specified.
                if (selectExpandDifferentFromQueryOptions != null)
                {
                    writeContext.SelectExpandClause = selectExpandDifferentFromQueryOptions;
                }

                serializer.WriteObject(value, type, messageWriter, writeContext);
            }
        }
Example #17
0
        private void WriteResponseBody(OutputFormatterContext context)
        {
            HttpRequest  request  = context.ActionContext.HttpContext.Request;
            HttpResponse response = context.ActionContext.HttpContext.Response;

            IEdmModel model = request.ODataProperties().Model;

            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
            }

            object          value      = context.Object;
            Type            type       = value.GetType();
            ODataSerializer serializer = GetSerializer(type, value, model, new DefaultODataSerializerProvider(), request);

            IUrlHelper urlHelper = context.ActionContext.HttpContext.UrlHelper();

            ODataPath            path = request.ODataProperties().Path;
            IEdmNavigationSource targetNavigationSource = path == null ? null : path.NavigationSource;

            string preferHeader     = RequestPreferenceHelpers.GetRequestPreferHeader(request);
            string annotationFilter = null;

            if (!String.IsNullOrEmpty(preferHeader))
            {
                ODataMessageWrapper messageWrapper = new ODataMessageWrapper(response.Body, response.Headers);
                messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader);
                annotationFilter = messageWrapper.PreferHeader().AnnotationFilter;
            }

            IODataResponseMessage responseMessage = new ODataMessageWrapper(response.Body, response.Headers);

            if (annotationFilter != null)
            {
                responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter;
            }

            Uri baseAddress = GetBaseAddress(request);
            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings(_messageWriterSettings)
            {
                PayloadBaseUri = baseAddress,
                Version        = ODataProperties.DefaultODataVersion,
            };

            string metadataLink = urlHelper.CreateODataLink(new MetadataPathSegment());

            if (metadataLink == null)
            {
                throw new SerializationException(SRResources.UnableToDetermineMetadataUrl);
            }

            writerSettings.ODataUri = new ODataUri
            {
                ServiceRoot = baseAddress,

                // TODO: 1604 Convert webapi.odata's ODataPath to ODL's ODataPath, or use ODL's ODataPath.
                SelectAndExpand = request.ODataProperties().SelectExpandClause,
                Path            = (path == null || IsOperationPath(path)) ? null : path.ODLPath,
            };

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model))
            {
                ODataSerializerContext writeContext = new ODataSerializerContext()
                {
                    Request          = request,
                    RequestContext   = request.HttpContext,
                    Url              = urlHelper,
                    NavigationSource = targetNavigationSource,
                    Model            = model,
                    RootElementName  = GetRootElementName(path) ?? "root",
                    SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed,
                    Path               = path,
                    MetadataLevel      = ODataMediaTypes.GetMetadataLevel(context.SelectedContentType),
                    SelectExpandClause = request.ODataProperties().SelectExpandClause
                };

                serializer.WriteObject(value, type, messageWriter, writeContext);
            }
        }
        /// <inheritdoc/>
        public override async Task <HttpResponseMessage> ProcessBatchAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            ValidateRequest(request);

            ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings
            {
                DisableMessageStreamDisposal = true,
                MessageQuotas = MessageQuotas,
                BaseUri       = GetBaseUri(request)
            };

            ODataMessageReader reader = await request.Content.GetODataMessageReaderAsync(oDataReaderSettings, cancellationToken);

            request.RegisterForDispose(reader);

            ODataBatchReader batchReader            = reader.CreateODataBatchReader();
            List <ODataBatchResponseItem> responses = new List <ODataBatchResponseItem>();
            Guid batchId = Guid.NewGuid();
            List <IDisposable> resourcesToDispose = new List <IDisposable>();

            string preferHeader = RequestPreferenceHelpers.GetRequestPreferHeader(request);

            if ((preferHeader != null && preferHeader.Contains(PreferenceContinueOnError)) || (!request.GetConfiguration().HasEnabledContinueOnErrorHeader()))
            {
                ContinueOnError = true;
            }
            else
            {
                ContinueOnError = false;
            }
            try
            {
                while (batchReader.Read())
                {
                    ODataBatchResponseItem responseItem = null;
                    if (batchReader.State == ODataBatchReaderState.ChangesetStart)
                    {
                        responseItem = await ExecuteChangeSetAsync(batchReader, batchId, request, cancellationToken);
                    }
                    else if (batchReader.State == ODataBatchReaderState.Operation)
                    {
                        responseItem = await ExecuteOperationAsync(batchReader, batchId, request, cancellationToken);
                    }
                    if (responseItem != null)
                    {
                        responses.Add(responseItem);
                        if (responseItem.IsResponseSuccessful() == false && ContinueOnError == false)
                        {
                            break;
                        }
                    }
                }
            }
            catch
            {
                foreach (ODataBatchResponseItem response in responses)
                {
                    if (response != null)
                    {
                        response.Dispose();
                    }
                }
                throw;
            }

            return(await CreateResponseMessageAsync(responses, request, cancellationToken));
        }
Example #19
0
        public virtual IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings)
        {
            if (query == null)
            {
                throw Error.ArgumentNull("query");
            }

            if (querySettings == null)
            {
                throw Error.ArgumentNull("querySettings");
            }

            IQueryable result = query;

            // First apply $apply
            // Section 3.15 of the spec http://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/cs01/odata-data-aggregation-ext-v4.0-cs01.html#_Toc378326311
            ApplyClause apply = null;

            if (IsAvailableODataQueryOption(Apply, AllowedQueryOptions.Apply))
            {
                result = Apply.ApplyTo(result, querySettings);
                InternalRequest.Context.ApplyClause = Apply.ApplyClause;
                this.Context.ElementClrType         = Apply.ResultClrType;
                apply = Apply.ApplyClause;
            }

            // Construct the actual query and apply them in the following order: filter, orderby, skip, top
            if (IsAvailableODataQueryOption(Filter, AllowedQueryOptions.Filter))
            {
                result = Filter.ApplyTo(result, querySettings);
            }

            if (IsAvailableODataQueryOption(Count, AllowedQueryOptions.Count))
            {
                if (InternalRequest.Context.TotalCountFunc == null)
                {
                    Func <long> countFunc = Count.GetEntityCountFunc(result);
                    if (countFunc != null)
                    {
                        InternalRequest.Context.TotalCountFunc = countFunc;
                    }
                }

                if (InternalRequest.IsCountRequest())
                {
                    return(result);
                }
            }

            OrderByQueryOption orderBy = OrderBy;

            // $skip or $top require a stable sort for predictable results.
            // Result limits require a stable sort to be able to generate a next page link.
            // If either is present in the query and we have permission,
            // generate an $orderby that will produce a stable sort.
            if (querySettings.EnsureStableOrdering &&
                (IsAvailableODataQueryOption(Skip, AllowedQueryOptions.Skip) ||
                 IsAvailableODataQueryOption(Top, AllowedQueryOptions.Top) ||
                 querySettings.PageSize.HasValue))
            {
                // If there is no OrderBy present, we manufacture a default.
                // If an OrderBy is already present, we add any missing
                // properties necessary to make a stable sort.
                // Instead of failing early here if we cannot generate the OrderBy,
                // let the IQueryable backend fail (if it has to).
                List <string> applySortOptions = GetApplySortOptions(apply);

                orderBy = orderBy == null
                            ? GenerateDefaultOrderBy(Context, applySortOptions)
                            : EnsureStableSortOrderBy(orderBy, Context, applySortOptions);
            }

            if (IsAvailableODataQueryOption(orderBy, AllowedQueryOptions.OrderBy))
            {
                result = orderBy.ApplyTo(result, querySettings);
            }

            AddAutoSelectExpandProperties();

            if (SelectExpand != null)
            {
                var tempResult = ApplySelectExpand(result, querySettings);
                if (tempResult != default(IQueryable))
                {
                    result = tempResult;
                }
            }

            if (IsAvailableODataQueryOption(Skip, AllowedQueryOptions.Skip))
            {
                result = Skip.ApplyTo(result, querySettings);
            }

            if (IsAvailableODataQueryOption(Top, AllowedQueryOptions.Top))
            {
                result = Top.ApplyTo(result, querySettings);
            }

            int pageSize = -1;

            if (querySettings.PageSize.HasValue)
            {
                pageSize = querySettings.PageSize.Value;
            }
            else if (querySettings.ModelBoundPageSize.HasValue)
            {
                pageSize = querySettings.ModelBoundPageSize.Value;
            }

            int preferredPageSize = -1;

            if (RequestPreferenceHelpers.RequestPrefersMaxPageSize(InternalRequest.Headers, out preferredPageSize))
            {
                pageSize = Math.Min(pageSize, preferredPageSize);
            }

            if (pageSize > 0)
            {
                bool resultsLimited;
                result = LimitResults(result, pageSize, out resultsLimited);
                if (resultsLimited && InternalRequest.RequestUri != null && InternalRequest.RequestUri.IsAbsoluteUri &&
                    InternalRequest.Context.NextLink == null)
                {
                    Uri nextPageLink = InternalRequest.GetNextPageLink(pageSize);
                    InternalRequest.Context.NextLink = nextPageLink;
                }
            }

            return(result);
        }