public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage) { responseMessage.SetStatusCode(HttpStatusCode.OK); using (var writer = this.CreateMessageWriter(responseMessage)) { writer.WriteServiceDocument(this.GenerateServiceDocument()); } }
public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage) { responseMessage.SetStatusCode(HttpStatusCode.OK); using (var writer = this.CreateMessageWriter(responseMessage)) { writer.WriteMetadataDocument(); } }
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; } }
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; } }
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; } }
/// <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()) { } } }
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); } }
/// <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()) { } } }
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); } }
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(); } }
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); } } }
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); } } }
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); } }
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; } }