private HttpResponseMessage CreateQueryResponse( IQueryable query, IEdmType edmType, bool isIfNoneMatch, ETag etag) { IEdmTypeReference typeReference = GetTypeReference(edmType); BaseSingleResult singleResult = null; HttpResponseMessage response = null; if (typeReference.IsPrimitive()) { if (this.shouldReturnCount || this.shouldWriteRawValue) { var rawResult = new RawResult(query, typeReference, this.Api.Context); singleResult = rawResult; response = this.Request.CreateResponse(HttpStatusCode.OK, rawResult); } else { var primitiveResult = new PrimitiveResult(query, typeReference, this.Api.Context); singleResult = primitiveResult; response = this.Request.CreateResponse(HttpStatusCode.OK, primitiveResult); } } if (typeReference.IsComplex()) { var complexResult = new ComplexResult(query, typeReference, this.Api.Context); singleResult = complexResult; response = this.Request.CreateResponse(HttpStatusCode.OK, complexResult); } if (typeReference.IsEnum()) { if (this.shouldWriteRawValue) { var rawResult = new RawResult(query, typeReference, this.Api.Context); singleResult = rawResult; response = this.Request.CreateResponse(HttpStatusCode.OK, rawResult); } else { var enumResult = new EnumResult(query, typeReference, this.Api.Context); singleResult = enumResult; response = this.Request.CreateResponse(HttpStatusCode.OK, enumResult); } } if (singleResult != null) { if (singleResult.Result == null) { // Per specification, If the property is single-valued and has the null value, // the service responds with 204 No Content. return this.Request.CreateResponse(HttpStatusCode.NoContent); } return response; } if (typeReference.IsCollection()) { var elementType = typeReference.AsCollection().ElementType(); if (elementType.IsPrimitive() || elementType.IsEnum()) { return this.Request.CreateResponse( HttpStatusCode.OK, new NonResourceCollectionResult(query, typeReference, this.Api.Context)); } return this.Request.CreateResponse( HttpStatusCode.OK, new ResourceSetResult(query, typeReference, this.Api.Context)); } var entityResult = query.SingleOrDefault(); if (entityResult == null) { return this.Request.CreateResponse(HttpStatusCode.NoContent); } // Check the ETag here if (etag != null) { // request with If-Match header, if match, then should return whole content // request with If-Match header, if not match, then should return 412 // request with If-None-Match header, if match, then should return 304 // request with If-None-Match header, if not match, then should return whole content etag.EntityType = query.ElementType; query = etag.ApplyTo(query); entityResult = query.SingleOrDefault(); if (entityResult == null && !isIfNoneMatch) { return this.Request.CreateResponse(HttpStatusCode.PreconditionFailed); } else if (entityResult == null) { return this.Request.CreateResponse(HttpStatusCode.NotModified); } } // Using reflection to create response for single entity so passed in parameter is not object type, // but will be type of real entity type, then EtagMessageHandler can be used to set ETAG header // when response is single entity. // There are three HttpRequestMessageExtensions class defined in different assembles var genericMethod = typeof(System.Net.Http.HttpRequestMessageExtensions).GetMethods() .Where(m => m.Name == "CreateResponse" && m.GetParameters().Length == 3); var method = genericMethod.FirstOrDefault().MakeGenericMethod(query.ElementType); response = method.Invoke(null, new object[] { this.Request, HttpStatusCode.OK, entityResult }) as HttpResponseMessage; return response; }
private HttpResponseMessage CreateQueryResponse( IQueryable query, IEdmType edmType, ETag etag) { IEdmTypeReference typeReference = GetTypeReference(edmType); BaseSingleResult singleResult = null; HttpResponseMessage response = null; if (typeReference.IsPrimitive()) { if (this.shouldReturnCount || this.shouldWriteRawValue) { var rawResult = new RawResult(query, typeReference); singleResult = rawResult; response = this.Request.CreateResponse(HttpStatusCode.OK, rawResult); } else { var primitiveResult = new PrimitiveResult(query, typeReference); singleResult = primitiveResult; response = this.Request.CreateResponse(HttpStatusCode.OK, primitiveResult); } } if (typeReference.IsComplex()) { var complexResult = new ComplexResult(query, typeReference); singleResult = complexResult; response = this.Request.CreateResponse(HttpStatusCode.OK, complexResult); } if (typeReference.IsEnum()) { if (this.shouldWriteRawValue) { var rawResult = new RawResult(query, typeReference); singleResult = rawResult; response = this.Request.CreateResponse(HttpStatusCode.OK, rawResult); } else { var enumResult = new EnumResult(query, typeReference); singleResult = enumResult; response = this.Request.CreateResponse(HttpStatusCode.OK, enumResult); } } if (singleResult != null) { if (singleResult.Result == null) { // Per specification, If the property is single-valued and has the null value, // the service responds with 204 No Content. return(this.Request.CreateResponse(HttpStatusCode.NoContent)); } return(response); } if (typeReference.IsCollection()) { var elementType = typeReference.AsCollection().ElementType(); if (elementType.IsPrimitive() || elementType.IsEnum()) { return(this.Request.CreateResponse( HttpStatusCode.OK, new NonResourceCollectionResult(query, typeReference))); } return(this.Request.CreateResponse( HttpStatusCode.OK, new ResourceSetResult(query, typeReference))); } var entityResult = query.SingleOrDefault(); if (entityResult == null) { return(this.Request.CreateResponse(HttpStatusCode.NoContent)); } // Check the ETag here if (etag != null) { // request with If-Match header, if match, then should return whole content // request with If-Match header, if not match, then should return 412 // request with If-None-Match header, if match, then should return 304 // request with If-None-Match header, if not match, then should return whole content etag.EntityType = query.ElementType; query = etag.ApplyTo(query); entityResult = query.SingleOrDefault(); if (entityResult == null && !etag.IsIfNoneMatch) { return(this.Request.CreateResponse(HttpStatusCode.PreconditionFailed)); } else if (entityResult == null) { return(this.Request.CreateResponse(HttpStatusCode.NotModified)); } } // Using reflection to create response for single entity so passed in parameter is not object type, // but will be type of real entity type, then EtagMessageHandler can be used to set ETAG header // when response is single entity. // There are three HttpRequestMessageExtensions class defined in different assembles var genericMethod = typeof(System.Net.Http.HttpRequestMessageExtensions).GetMethods() .Where(m => m.Name == "CreateResponse" && m.GetParameters().Length == 3); var method = genericMethod.FirstOrDefault().MakeGenericMethod(query.ElementType); response = method.Invoke(null, new object[] { this.Request, HttpStatusCode.OK, entityResult }) as HttpResponseMessage; return(response); }