Beispiel #1
0
        private HttpResponseMessage CreateQueryResponse(IQueryable query, IEdmType edmType, ETag etag)
        {
            var typeReference = GetTypeReference(edmType);
            BaseSingleResult    singleResult = null;
            HttpResponseMessage response     = null;

            if (typeReference.IsPrimitive())
            {
                if (shouldReturnCount || shouldWriteRawValue)
                {
                    var rawResult = new RawResult(query, typeReference);
                    singleResult = rawResult;
                    response     = Request.CreateResponse(HttpStatusCode.OK, rawResult);
                }
                else
                {
                    var primitiveResult = new PrimitiveResult(query, typeReference);
                    singleResult = primitiveResult;
                    response     = Request.CreateResponse(HttpStatusCode.OK, primitiveResult);
                }
            }

            if (typeReference.IsComplex())
            {
                var complexResult = new ComplexResult(query, typeReference);
                singleResult = complexResult;
                response     = Request.CreateResponse(HttpStatusCode.OK, complexResult);
            }

            if (typeReference.IsEnum())
            {
                if (shouldWriteRawValue)
                {
                    var rawResult = new RawResult(query, typeReference);
                    singleResult = rawResult;
                    response     = Request.CreateResponse(HttpStatusCode.OK, rawResult);
                }
                else
                {
                    var enumResult = new EnumResult(query, typeReference);
                    singleResult = enumResult;
                    response     = 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(Request.CreateResponse(HttpStatusCode.NoContent));
                }

                return(response);
            }

            if (typeReference.IsCollection())
            {
                var elementType = typeReference.AsCollection().ElementType();
                if (elementType.IsPrimitive() || elementType.IsEnum())
                {
                    return(Request.CreateResponse(HttpStatusCode.OK, new NonResourceCollectionResult(query, typeReference)));
                }

                return(Request.CreateResponse(HttpStatusCode.OK, new ResourceSetResult(query, typeReference)));
            }

            var entityResult = query.SingleOrDefault();

            if (entityResult == null)
            {
                return(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(Request.CreateResponse(HttpStatusCode.PreconditionFailed));
                }
                else if (entityResult == null)
                {
                    return(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

            // Fix by @xuzhg in PR #609.
            var assembly      = System.Reflection.Assembly.GetAssembly(typeof(AcceptVerbsAttribute));
            var type          = assembly.GetType("System.Net.Http.HttpRequestMessageExtensions");
            var genericMethod = type.GetMethods()
                                .Where(m => m.Name == "CreateResponse" && m.GetParameters().Length == 3);
            var method = genericMethod.FirstOrDefault().MakeGenericMethod(query.ElementType);

            response = method.Invoke(null, new object[] { Request, HttpStatusCode.OK, entityResult }) as HttpResponseMessage;
            return(response);
        }