public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
 {
     responseMessage.SetStatusCode(HttpStatusCode.OK);
     using (var writer = this.CreateMessageWriter(responseMessage))
     {
         writer.WriteServiceDocument(this.GenerateServiceDocument());
     }
 }
Ejemplo n.º 2
0
 public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
 {
     responseMessage.SetStatusCode(HttpStatusCode.OK);
     using (var writer = this.CreateMessageWriter(responseMessage))
     {
         writer.WriteMetadataDocument();
     }
 }
Ejemplo n.º 3
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            if (this.TryDispatch(requestMessage, responseMessage))
            {
                return;
            }

            if (this.QueryContext.Target.TypeKind != EdmTypeKind.Collection)
            {
                throw Utility.BuildException(HttpStatusCode.BadRequest, "The new resource can only be created under collection resource.", null);
            }

            if (this.QueryContext.Target.IsReference)
            {
                this.ProcessCreateLink(requestMessage, responseMessage);
                return;
            }

            try
            {
                var targetEntitySet = (IEdmEntitySetBase)this.QueryContext.Target.NavigationSource;

                // TODO: [lianw] Try to remove "targetEntitySet" later.
                var queryResults = this.QueryContext.ResolveQuery(this.DataSource);

                if (!IsAllowInsert(targetEntitySet as IEdmEntitySet))
                {
                    throw new ODataServiceException(HttpStatusCode.BadRequest, "The insert request is not allowed.", null);
                }

                var bodyObject = ProcessPostBody(requestMessage, targetEntitySet, queryResults);

                using (var messageWriter = this.CreateMessageWriter(responseMessage))
                {
                    this.DataSource.UpdateProvider.SaveChanges();

                    // 11.4.2 Create an Entity
                    // Upon successful completion the service MUST respond with either 201 Created, or 204 No Content if the request included a return Prefer header with a value of return=minimal.
                    responseMessage.SetStatusCode(HttpStatusCode.Created);
                    responseMessage.SetHeader(ServiceConstants.HttpHeaders.Location, Utility.BuildLocationUri(this.QueryContext, bodyObject).OriginalString);
                    var currentETag = Utility.GetETagValue(bodyObject);
                    // if the current entity has ETag field
                    if (currentETag != null)
                    {
                        responseMessage.SetHeader(ServiceConstants.HttpHeaders.ETag, currentETag);
                    }

                    ResponseWriter.WriteEntry(messageWriter.CreateODataResourceWriter(targetEntitySet), bodyObject, targetEntitySet, ODataVersion.V4, null);
                }
            }
            catch
            {
                this.DataSource.UpdateProvider.ClearChanges();
                throw;
            }
        }
Ejemplo n.º 4
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            if (this.TryDispatch(requestMessage, responseMessage))
            {
                return;
            }

            if (this.QueryContext.Target.TypeKind != EdmTypeKind.Collection)
            {
                throw Utility.BuildException(HttpStatusCode.BadRequest, "The new resource can only be created under collection resource.", null);
            }

            if (this.QueryContext.Target.IsReference)
            {
                this.ProcessCreateLink(requestMessage, responseMessage);
                return;
            }

            try
            {
                var targetEntitySet = (IEdmEntitySetBase)this.QueryContext.Target.NavigationSource;

                // TODO: [lianw] Try to remove "targetEntitySet" later.
                var queryResults = this.QueryContext.ResolveQuery(this.DataSource);

                if (!IsAllowInsert(targetEntitySet as IEdmEntitySet))
                {
                    throw new ODataServiceException(HttpStatusCode.BadRequest, "The insert request is not allowed.", null);
                }

                var bodyObject = ProcessPostBody(requestMessage, targetEntitySet, queryResults);

                using (var messageWriter = this.CreateMessageWriter(responseMessage))
                {
                    this.DataSource.UpdateProvider.SaveChanges();

                    // 11.4.2 Create an Entity
                    // Upon successful completion the service MUST respond with either 201 Created, or 204 No Content if the request included a return Prefer header with a value of return=minimal.
                    responseMessage.SetStatusCode(HttpStatusCode.Created);
                    responseMessage.SetHeader(ServiceConstants.HttpHeaders.Location, Utility.BuildLocationUri(this.QueryContext, bodyObject).OriginalString);
                    var currentETag = Utility.GetETagValue(bodyObject);
                    // if the current entity has ETag field
                    if (currentETag != null)
                    {
                        responseMessage.SetHeader(ServiceConstants.HttpHeaders.ETag, currentETag);
                    }

                    ResponseWriter.WriteEntry(messageWriter.CreateODataEntryWriter(targetEntitySet), bodyObject, targetEntitySet, ODataVersion.V4, null);
                }
            }
            catch
            {
                this.DataSource.UpdateProvider.ClearChanges();
                throw;
            }
        }
Ejemplo n.º 5
0
        private void ProcessCreate(Stream requestStream, IODataResponseMessage responseMessage)
        {
            try
            {
                // handle insert annotation
                if (!this.IsAllowInsert(this.QueryContext.Target.NavigationSource as IEdmEntitySet))
                {
                    throw new ODataServiceException(HttpStatusCode.BadRequest, "The insert request is not allowed.", null);
                }

                // handle content type
                var contentType = this.HandleContentType((IEdmEntityType)this.QueryContext.Target.ElementType);

                // handle entity
                var entities = this.QueryContext.ResolveQuery(this.DataSource);
                var entity   = this.DataSource.UpdateProvider.Create(this.QueryContext.Target.ElementType.FullTypeName(), entities);
                this.DataSource.StreamProvider.CreateStream(entity, requestStream, contentType);

                this.DataSource.UpdateProvider.SaveChanges();

                using (var messageWriter = this.CreateMessageWriter(responseMessage))
                {
                    responseMessage.SetHeader(ServiceConstants.HttpHeaders.Location, Utility.BuildLocationUri(this.QueryContext, entity).OriginalString);

                    if (this.PreferenceContext.Return == ServiceConstants.PreferenceValue_Return_Minimal)
                    {
                        responseMessage.SetStatusCode(HttpStatusCode.NoContent);
                    }
                    else
                    {
                        responseMessage.SetStatusCode(HttpStatusCode.Created);
                        var edmEntitySet = (IEdmEntitySetBase)this.QueryContext.Target.NavigationSource;
                        ResponseWriter.WriteEntry(messageWriter.CreateODataResourceWriter(edmEntitySet), entity, edmEntitySet, ODataVersion.V4, null);
                    }
                }
            }
            catch
            {
                this.DataSource.UpdateProvider.ClearChanges();
                throw;
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Write empty response and set the HttpStatusCode to 204 NoContent
 /// </summary>
 /// <param name="responseMessage"></param>
 public static void WriteEmptyResponse(IODataResponseMessage responseMessage, HttpStatusCode statusCode = HttpStatusCode.NoContent)
 {
     responseMessage.SetStatusCode(statusCode);
     responseMessage.SetHeader("OData-Version", "4.0");
     if (!(responseMessage is ODataBatchOperationResponseMessage))
     {
         using (responseMessage.GetStream())
         {
         }
     }
 }
Ejemplo n.º 7
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            using (var messageWriter = this.CreateMessageWriter(responseMessage))
            {
                ODataError error;
                HttpStatusCode statusCode;

                this.BuildODataError(out error, out statusCode);
                responseMessage.SetStatusCode(statusCode);
                messageWriter.WriteError(error, true);
            }
        }
Ejemplo n.º 8
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            using (var messageWriter = this.CreateMessageWriter(responseMessage))
            {
                ODataError     error;
                HttpStatusCode statusCode;

                this.BuildODataError(out error, out statusCode);
                responseMessage.SetStatusCode(statusCode);
                messageWriter.WriteError(error, true);
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Write empty response and set the HttpStatusCode to 202 Accepted
        /// </summary>
        /// <param name="responseMessage"></param>
        /// <param name="asyncToken"></param>
        public static void WriteAsyncPendingResponse(IODataResponseMessage responseMessage, string asyncToken)
        {
            responseMessage.SetStatusCode(HttpStatusCode.Accepted);
            responseMessage.SetHeader(ServiceConstants.HttpHeaders.DataServiceVersion, "4.0");
            Uri location = new Uri(ServiceConstants.ServiceBaseUri, string.Format("{0}?{1}={2}", ServiceConstants.ServicePath_Async, ServiceConstants.QueryOption_AsyncToken, asyncToken));

            responseMessage.SetHeader(ServiceConstants.HttpHeaders.Location, location.OriginalString);

            if (!(responseMessage is ODataBatchOperationResponseMessage))
            {
                using (responseMessage.GetStream())
                {
                }
            }
        }
Ejemplo n.º 10
0
        private void ProcessUpdate(Stream requestStream, IODataResponseMessage responseMessage)
        {
            // handle entity
            var entity = this.HandleEntity();

            // handle content type
            var parentUri     = this.QueryContext.Target.BuildContainerUri(this.ServiceRootUri);
            var parentContext = new QueryContext(this.ServiceRootUri, parentUri, this.DataSource.Model, this.RequestContainer);
            var contentType   = this.HandleContentType((IEdmEntityType)parentContext.Target.ElementType);

            // handle ETag
            this.HandleETag(entity, true);

            // handle update
            this.DataSource.StreamProvider.UpdateStream(entity, requestStream, contentType);

            using (var messageWriter = this.CreateMessageWriter(responseMessage))
            {
                responseMessage.SetStatusCode(HttpStatusCode.OK);
                var edmEntitySet = (IEdmEntitySetBase)parentContext.Target.NavigationSource;
                ResponseWriter.WriteEntry(messageWriter.CreateODataResourceWriter(edmEntitySet), entity, edmEntitySet, ODataVersion.V4, null);
            }
        }
Ejemplo n.º 11
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            responseMessage.SetStatusCode(HttpStatusCode.OK);

            using (var batchRequestMessageWriter = this.CreateMessageWriter(responseMessage))
            {
                var batchWriter = batchRequestMessageWriter.CreateODataBatchWriter();
                batchWriter.WriteStartBatch();

                using (var batchRequestMessageReader = this.CreateMessageReader(requestMessage))
                {
                    var batchReader = batchRequestMessageReader.CreateODataBatchReader();

                    while (batchReader.Read())
                    {
                        switch (batchReader.State)
                        {
                        case ODataBatchReaderState.Initial:
                            break;

                        case ODataBatchReaderState.ChangesetStart:
                            batchWriter.WriteStartChangeset();
                            break;

                        case ODataBatchReaderState.ChangesetEnd:
                            batchWriter.WriteEndChangeset();
                            break;

                        case ODataBatchReaderState.Operation:
                            ODataBatchOperationRequestMessage operationRequestMessage =
                                batchReader.CreateOperationRequestMessage();

                            ODataBatchOperationResponseMessage operationResponseMessage =
                                batchWriter.CreateOperationResponseMessage(operationRequestMessage.ContentId);

                            HttpMethod method = Utility.CreateHttpMethod(operationRequestMessage.Method);

                            switch (method)
                            {
                            case HttpMethod.GET:
                                new QueryHandler(this, operationRequestMessage.Url, operationRequestMessage.Headers).Process(operationRequestMessage, operationResponseMessage);
                                break;

                            case HttpMethod.POST:
                                new CreateHandler(this, operationRequestMessage.Url, operationRequestMessage.Headers).Process(operationRequestMessage, operationResponseMessage);
                                break;

                            case HttpMethod.DELETE:
                                new DeleteHandler(this, operationRequestMessage.Url, operationRequestMessage.Headers).Process(operationRequestMessage, operationResponseMessage);
                                break;

                            case HttpMethod.PATCH:
                            case HttpMethod.PUT:
                                new UpdateHandler(this, method, operationRequestMessage.Url, operationRequestMessage.Headers).Process(operationRequestMessage, operationResponseMessage);
                                break;

                            default:
                                new ErrorHandler(this, Utility.BuildException(HttpStatusCode.MethodNotAllowed)).Process(operationRequestMessage, operationResponseMessage);
                                break;
                            }

                            break;
                        }
                    }
                }

                batchWriter.WriteEndBatch();
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Write empty response and set the HttpStatusCode to 202 Accepted
        /// </summary>
        /// <param name="responseMessage"></param>
        /// <param name="asyncToken"></param>
        public static void WriteAsyncPendingResponse(IODataResponseMessage responseMessage, string asyncToken)
        {
            responseMessage.SetStatusCode(HttpStatusCode.Accepted);
            responseMessage.SetHeader(ServiceConstants.HttpHeaders.DataServiceVersion, "4.0");
            Uri location = new Uri(ServiceConstants.ServiceBaseUri, string.Format("{0}?{1}={2}", ServiceConstants.ServicePath_Async, ServiceConstants.QueryOption_AsyncToken, asyncToken));
            responseMessage.SetHeader(ServiceConstants.HttpHeaders.Location, location.OriginalString);

            if (!(responseMessage is ODataBatchOperationResponseMessage))
            {
                using (responseMessage.GetStream())
                {
                }
            }
        }
Ejemplo n.º 13
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            responseMessage.SetStatusCode(HttpStatusCode.OK);

            using (var batchRequestMessageWriter = this.CreateMessageWriter(responseMessage))
            {
                var batchWriter = batchRequestMessageWriter.CreateODataBatchWriter();
                batchWriter.WriteStartBatch();

                using (var batchRequestMessageReader = this.CreateMessageReader(requestMessage))
                {
                    var batchReader = batchRequestMessageReader.CreateODataBatchReader();

                    while (batchReader.Read())
                    {
                        switch (batchReader.State)
                        {
                            case ODataBatchReaderState.Initial:
                                break;
                            case ODataBatchReaderState.ChangesetStart:
                                batchWriter.WriteStartChangeset();
                                break;
                            case ODataBatchReaderState.ChangesetEnd:
                                batchWriter.WriteEndChangeset();
                                break;
                            case ODataBatchReaderState.Operation:
                                ODataBatchOperationRequestMessage operationRequestMessage =
                                    batchReader.CreateOperationRequestMessage();

                                ODataBatchOperationResponseMessage operationResponseMessage =
                                    batchWriter.CreateOperationResponseMessage(operationRequestMessage.ContentId);

                                HttpMethod method = Utility.CreateHttpMethod(operationRequestMessage.Method);

                                switch (method)
                                {
                                    case HttpMethod.GET:
                                        new QueryHandler(this, operationRequestMessage.Url, operationRequestMessage.Headers).Process(operationRequestMessage, operationResponseMessage);
                                        break;
                                    case HttpMethod.POST:
                                        new CreateHandler(this, operationRequestMessage.Url, operationRequestMessage.Headers).Process(operationRequestMessage, operationResponseMessage);
                                        break;
                                    case HttpMethod.DELETE:
                                        new DeleteHandler(this, operationRequestMessage.Url, operationRequestMessage.Headers).Process(operationRequestMessage, operationResponseMessage);
                                        break;
                                    case HttpMethod.PATCH:
                                    case HttpMethod.PUT:
                                        new UpdateHandler(this, method, operationRequestMessage.Url, operationRequestMessage.Headers).Process(operationRequestMessage, operationResponseMessage);
                                        break;
                                    default:
                                        new ErrorHandler(this, Utility.BuildException(HttpStatusCode.MethodNotAllowed)).Process(operationRequestMessage, operationResponseMessage);
                                        break;
                                }

                                break;
                        }
                    }
                }

                batchWriter.WriteEndBatch();
            }

        }
Ejemplo n.º 14
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            if (this.TryDispatch(requestMessage, responseMessage))
            {
                return;
            }

            this.QueryContext.InitializeServerDrivenPaging(this.PreferenceContext);
            this.QueryContext.InitializeTrackingChanges(this.PreferenceContext);

            object queryResults = this.QueryContext.ResolveQuery(this.DataSource);

            if (queryResults == null)
            {
                // For individual property or $value
                if (this.QueryContext.Target.Property != null)
                {
                    // Protocol 9.1.4 Response Code 204 No Content
                    // A request returns 204 No Content if the requested resource has the null value,
                    // or if the service applies a return=minimal preference. In this case, the response body MUST be empty.
                    ResponseWriter.WriteEmptyResponse(responseMessage);

                    return;
                }
                else
                {
                    throw Utility.BuildException(HttpStatusCode.NotFound);
                }
            }

            // Handle the prefer of "odata.include-annotations", including it in response header
            if (!string.IsNullOrEmpty(this.PreferenceContext.IncludeAnnotations))
            {
                responseMessage.AddPreferenceApplied(string.Format("{0}={1}",
                                                                   ServiceConstants.Preference_IncludeAnnotations, this.PreferenceContext.IncludeAnnotations));
            }

            if (this.PreferenceContext.MaxPageSize.HasValue)
            {
                responseMessage.AddPreferenceApplied(string.Format("{0}={1}", ServiceConstants.Preference_MaxPageSize, this.QueryContext.appliedPageSize.Value));
            }

            if (this.PreferenceContext.TrackingChanges)
            {
                responseMessage.AddPreferenceApplied(ServiceConstants.Preference_TrackChanging);
            }

            responseMessage.SetStatusCode(HttpStatusCode.OK);

            using (var messageWriter = this.CreateMessageWriter(responseMessage))
            {
                IEdmNavigationSource navigationSource   = this.QueryContext.Target.NavigationSource;
                IEnumerable          iEnumerableResults = queryResults as IEnumerable;

                if (this.QueryContext.Target.IsReference && this.QueryContext.Target.TypeKind == EdmTypeKind.Collection)
                {
                    // Query a $ref collection
                    IList <ODataEntityReferenceLink> links = new List <ODataEntityReferenceLink>();

                    foreach (var iEnumerableResult in iEnumerableResults)
                    {
                        var link = new ODataEntityReferenceLink
                        {
                            Url = Utility.BuildLocationUri(this.QueryContext, iEnumerableResult),
                        };
                        links.Add(link);
                    }

                    ODataEntityReferenceLinks linksCollection = new ODataEntityReferenceLinks()
                    {
                        Links = links, NextPageLink = this.QueryContext.NextLink
                    };
                    linksCollection.InstanceAnnotations.Add(new ODataInstanceAnnotation("Links.Annotation", new ODataPrimitiveValue(true)));
                    messageWriter.WriteEntityReferenceLinks(linksCollection);
                }
                else if (this.QueryContext.Target.IsReference && this.QueryContext.Target.TypeKind == EdmTypeKind.Entity)
                {
                    // Query a $ref
                    var link = new ODataEntityReferenceLink
                    {
                        Url = Utility.BuildLocationUri(this.QueryContext, queryResults),
                    };
                    link.InstanceAnnotations.Add(new ODataInstanceAnnotation("Link.Annotation", new ODataPrimitiveValue(true)));

                    messageWriter.WriteEntityReferenceLink(link);
                }
                else if (this.QueryContext.Target.NavigationSource != null && this.QueryContext.Target.TypeKind == EdmTypeKind.Collection)
                {
                    // Query a feed
                    IEdmEntitySetBase entitySet  = navigationSource as IEdmEntitySetBase;
                    IEdmEntityType    entityType = this.QueryContext.Target.ElementType as IEdmEntityType;

                    if (entitySet == null || entityType == null)
                    {
                        throw new InvalidOperationException("Invalid target when query feed.");
                    }

                    ODataWriter resultWriter = messageWriter.CreateODataFeedWriter(entitySet, entityType);

                    ResponseWriter.WriteFeed(resultWriter, iEnumerableResults, entitySet, ODataVersion.V4, this.QueryContext.QuerySelectExpandClause, this.QueryContext.TotalCount, this.QueryContext.DeltaLink, this.QueryContext.NextLink, this.RequestHeaders);
                    resultWriter.Flush();
                }
                else if (this.QueryContext.Target.NavigationSource != null && this.QueryContext.Target.TypeKind == EdmTypeKind.Entity)
                {
                    var currentETag = Utility.GetETagValue(queryResults);
                    // if the current entity has ETag field
                    if (currentETag != null)
                    {
                        string requestETag;
                        if (Utility.TryGetIfNoneMatch(this.RequestHeaders, out requestETag) && (requestETag == ServiceConstants.ETagValueAsterisk || requestETag == currentETag))
                        {
                            ResponseWriter.WriteEmptyResponse(responseMessage, HttpStatusCode.NotModified);
                            return;
                        }

                        responseMessage.SetHeader(ServiceConstants.HttpHeaders.ETag, currentETag);
                    }

                    // Query a single entity
                    IEdmEntityType entityType = this.QueryContext.Target.Type as IEdmEntityType;

                    ODataWriter resultWriter = messageWriter.CreateODataEntryWriter(navigationSource, entityType);
                    ResponseWriter.WriteEntry(resultWriter, queryResults, navigationSource, ODataVersion.V4, this.QueryContext.QuerySelectExpandClause, this.RequestHeaders);
                    resultWriter.Flush();
                }
                else if (this.QueryContext.Target.Property != null && !this.QueryContext.Target.IsRawValue)
                {
                    // Query a individual property
                    ODataProperty property = ODataObjectModelConverter.CreateODataProperty(queryResults, this.QueryContext.Target.Property.Name);
                    messageWriter.WriteProperty(property);
                }
                else if (this.QueryContext.Target.IsRawValue)
                {
                    // Query a $value or $count
                    var propertyValue = ODataObjectModelConverter.CreateODataValue(queryResults);
                    messageWriter.WriteValue(propertyValue);
                }
                else
                {
                    throw Utility.BuildException(HttpStatusCode.NotImplemented);
                }
            }
        }
Ejemplo n.º 15
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            if (this.TryDispatch(requestMessage, responseMessage))
            {
                return;
            }

            this.QueryContext.InitializeServerDrivenPaging(this.PreferenceContext);
            this.QueryContext.InitializeTrackingChanges(this.PreferenceContext);

            object queryResults = this.QueryContext.ResolveQuery(this.DataSource);

            if (queryResults == null)
            {
                // For individual property or $value
                if (this.QueryContext.Target.Property != null)
                {
                    // Protocol 9.1.4 Response Code 204 No Content
                    // A request returns 204 No Content if the requested resource has the null value, 
                    // or if the service applies a return=minimal preference. In this case, the response body MUST be empty.
                    ResponseWriter.WriteEmptyResponse(responseMessage);

                    return;
                }
                else
                {
                    throw Utility.BuildException(HttpStatusCode.NotFound);
                }
            }

            // Handle the prefer of "odata.include-annotations", including it in response header
            if (!string.IsNullOrEmpty(this.PreferenceContext.IncludeAnnotations))
            {
                responseMessage.AddPreferenceApplied(string.Format("{0}={1}",
                    ServiceConstants.Preference_IncludeAnnotations, this.PreferenceContext.IncludeAnnotations));
            }

            if (this.PreferenceContext.MaxPageSize.HasValue)
            {
                responseMessage.AddPreferenceApplied(string.Format("{0}={1}", ServiceConstants.Preference_MaxPageSize, this.QueryContext.appliedPageSize.Value));
            }

            if (this.PreferenceContext.TrackingChanges)
            {
                responseMessage.AddPreferenceApplied(ServiceConstants.Preference_TrackChanging);
            }

            responseMessage.SetStatusCode(HttpStatusCode.OK);

            using (var messageWriter = this.CreateMessageWriter(responseMessage))
            {
                IEdmNavigationSource navigationSource = this.QueryContext.Target.NavigationSource;
                IEnumerable iEnumerableResults = queryResults as IEnumerable;

                if (this.QueryContext.Target.IsReference && this.QueryContext.Target.TypeKind == EdmTypeKind.Collection)
                {
                    // Query a $ref collection
                    IList<ODataEntityReferenceLink> links = new List<ODataEntityReferenceLink>();

                    foreach (var iEnumerableResult in iEnumerableResults)
                    {
                        var link = new ODataEntityReferenceLink
                        {
                            Url = Utility.BuildLocationUri(this.QueryContext, iEnumerableResult),
                        };
                        links.Add(link);
                    }

                    ODataEntityReferenceLinks linksCollection = new ODataEntityReferenceLinks() { Links = links, NextPageLink = this.QueryContext.NextLink };
                    linksCollection.InstanceAnnotations.Add(new ODataInstanceAnnotation("Links.Annotation", new ODataPrimitiveValue(true)));
                    messageWriter.WriteEntityReferenceLinks(linksCollection);
                }
                else if (this.QueryContext.Target.IsReference && this.QueryContext.Target.TypeKind == EdmTypeKind.Entity)
                {
                    // Query a $ref
                    var link = new ODataEntityReferenceLink
                    {
                        Url = Utility.BuildLocationUri(this.QueryContext, queryResults),
                    };
                    link.InstanceAnnotations.Add(new ODataInstanceAnnotation("Link.Annotation", new ODataPrimitiveValue(true)));

                    messageWriter.WriteEntityReferenceLink(link);
                }
                else if (this.QueryContext.Target.NavigationSource != null && this.QueryContext.Target.TypeKind == EdmTypeKind.Collection)
                {
                    // Query a feed
                    IEdmEntitySetBase entitySet = navigationSource as IEdmEntitySetBase;
                    IEdmEntityType entityType = this.QueryContext.Target.ElementType as IEdmEntityType;

                    if (entitySet == null || entityType == null)
                    {
                        throw new InvalidOperationException("Invalid target when query feed.");
                    }

                    ODataWriter resultWriter = messageWriter.CreateODataFeedWriter(entitySet, entityType);

                    ResponseWriter.WriteFeed(resultWriter, entityType, iEnumerableResults, entitySet, ODataVersion.V4, this.QueryContext.QuerySelectExpandClause, this.QueryContext.TotalCount, this.QueryContext.DeltaLink, this.QueryContext.NextLink, this.RequestHeaders);
                    resultWriter.Flush();
                }
                else if (this.QueryContext.Target.NavigationSource != null && this.QueryContext.Target.TypeKind == EdmTypeKind.Entity)
                {
                    var currentETag = Utility.GetETagValue(queryResults);
                    // if the current entity has ETag field
                    if (currentETag != null)
                    {
                        string requestETag;
                        if (Utility.TryGetIfNoneMatch(this.RequestHeaders, out requestETag) && (requestETag == ServiceConstants.ETagValueAsterisk || requestETag == currentETag))
                        {
                            ResponseWriter.WriteEmptyResponse(responseMessage, HttpStatusCode.NotModified);
                            return;
                        }

                        responseMessage.SetHeader(ServiceConstants.HttpHeaders.ETag, currentETag);
                    }

                    // Query a single entity
                    IEdmEntityType entityType = this.QueryContext.Target.Type as IEdmEntityType;

                    ODataWriter resultWriter = messageWriter.CreateODataEntryWriter(navigationSource, entityType);
                    ResponseWriter.WriteEntry(resultWriter, queryResults, navigationSource, ODataVersion.V4, this.QueryContext.QuerySelectExpandClause, this.RequestHeaders);
                    resultWriter.Flush();
                }
                else if (this.QueryContext.Target.Property != null && !this.QueryContext.Target.IsRawValue)
                {
                    // Query a individual property
                    ODataProperty property = ODataObjectModelConverter.CreateODataProperty(queryResults, this.QueryContext.Target.Property.Name);
                    messageWriter.WriteProperty(property);
                }
                else if (this.QueryContext.Target.IsRawValue)
                {
                    // Query a $value or $count
                    var propertyValue = ODataObjectModelConverter.CreateODataValue(queryResults);
                    messageWriter.WriteValue(propertyValue);
                }
                else
                {
                    throw Utility.BuildException(HttpStatusCode.NotImplemented);
                }
            }
        }
Ejemplo n.º 16
0
        private void ProcessUpdate(Stream requestStream, IODataResponseMessage responseMessage)
        {
            // handle entity
            var entity = this.HandleEntity();

            // handle content type
            var parentUri = this.QueryContext.Target.BuildContainerUri(this.ServiceRootUri);
            var parentContext = new QueryContext(this.ServiceRootUri, parentUri, this.DataSource.Model);
            var contentType = this.HandleContentType((IEdmEntityType)parentContext.Target.ElementType);

            // handle ETag
            this.HandleETag(entity, true);

            // handle update
            this.DataSource.StreamProvider.UpdateStream(entity, requestStream, contentType);

            using (var messageWriter = this.CreateMessageWriter(responseMessage))
            {
                responseMessage.SetStatusCode(HttpStatusCode.OK);
                var edmEntitySet = (IEdmEntitySetBase)parentContext.Target.NavigationSource;
                ResponseWriter.WriteEntry(messageWriter.CreateODataEntryWriter(edmEntitySet), entity, edmEntitySet, ODataVersion.V4, null);
            }
        }
Ejemplo n.º 17
0
        private void ProcessCreate(Stream requestStream, IODataResponseMessage responseMessage)
        {
            try
            {
                // handle insert annotation
                if (!this.IsAllowInsert(this.QueryContext.Target.NavigationSource as IEdmEntitySet))
                {
                    throw new ODataServiceException(HttpStatusCode.BadRequest, "The insert request is not allowed.", null);
                }

                // handle content type
                var contentType = this.HandleContentType((IEdmEntityType)this.QueryContext.Target.ElementType);

                // handle entity
                var entities = this.QueryContext.ResolveQuery(this.DataSource);
                var entity = this.DataSource.UpdateProvider.Create(this.QueryContext.Target.ElementType.FullTypeName(), entities);
                this.DataSource.StreamProvider.CreateStream(entity, requestStream, contentType);

                this.DataSource.UpdateProvider.SaveChanges();

                using (var messageWriter = this.CreateMessageWriter(responseMessage))
                {
                    responseMessage.SetHeader(ServiceConstants.HttpHeaders.Location, Utility.BuildLocationUri(this.QueryContext, entity).OriginalString);

                    if (this.PreferenceContext.Return == ServiceConstants.PreferenceValue_Return_Minimal)
                    {
                        responseMessage.SetStatusCode(HttpStatusCode.NoContent);
                    }
                    else
                    {
                        responseMessage.SetStatusCode(HttpStatusCode.Created);
                        var edmEntitySet = (IEdmEntitySetBase)this.QueryContext.Target.NavigationSource;
                        ResponseWriter.WriteEntry(messageWriter.CreateODataEntryWriter(edmEntitySet), entity, edmEntitySet, ODataVersion.V4, null);
                    }
                }
            }
            catch
            {
                this.DataSource.UpdateProvider.ClearChanges();
                throw;
            }
        }
Ejemplo n.º 18
0
 /// <summary>
 /// Write empty response and set the HttpStatusCode to 204 NoContent
 /// </summary>
 /// <param name="responseMessage"></param>
 public static void WriteEmptyResponse(IODataResponseMessage responseMessage, HttpStatusCode statusCode = HttpStatusCode.NoContent)
 {
     responseMessage.SetStatusCode(statusCode);
     responseMessage.SetHeader("OData-Version", "4.0");
     if (!(responseMessage is ODataBatchOperationResponseMessage))
     {
         using (responseMessage.GetStream())
         {
         }
     }
 }