Esempio n. 1
0
        /// <inheritdoc/>
        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            // Determine the content type or let base class handle it.
            MediaTypeHeaderValue newMediaType = null;

            if (ODataOutputFormatterHelper.TryGetContentHeader(type, mediaType, out newMediaType))
            {
                headers.ContentType = newMediaType;
            }
            else
            {
                // This is the case when a user creates a new ObjectContent<T> passing in a null mediaType
                base.SetDefaultContentHeaders(type, headers, mediaType);
            }

            // Set the character set.
            IEnumerable <string> acceptCharsetValues = Request.Headers.AcceptCharset.Select(cs => cs.Value);

            string newCharSet = String.Empty;

            if (ODataOutputFormatterHelper.TryGetCharSet(headers.ContentType, acceptCharsetValues, out newCharSet))
            {
                headers.ContentType.CharSet = newCharSet;
            }

            // Add version header.
            headers.TryAddWithoutValidation(
                ODataVersionConstraint.ODataServiceVersionHeader,
                ODataUtils.ODataVersionToString(ResultHelpers.GetODataResponseVersion(Request)));
        }
        internal static Task <HttpResponseMessage> CreateODataBatchResponseAsync(this HttpRequestMessage request, IEnumerable <ODataBatchResponseItem> responses, ODataMessageQuotas messageQuotas)
        {
            Contract.Assert(request != null);

            ODataVersion               odataVersion     = ResultHelpers.GetODataResponseVersion(request);
            IServiceProvider           requestContainer = request.GetRequestContainer();
            ODataMessageWriterSettings writerSettings   =
                requestContainer.GetRequiredService <ODataMessageWriterSettings>();

            writerSettings.Version       = odataVersion;
            writerSettings.MessageQuotas = messageQuotas;

            MediaTypeHeaderValue responseContentType = null;

            if (request.Headers.Accept.Any(
                    t => t.MediaType.Equals(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeMime, StringComparison.OrdinalIgnoreCase)))
            {
                responseContentType = MediaTypeHeaderValue.Parse(
                    String.Format(CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}",
                                  Guid.NewGuid()));
            }
            else if (request.Headers.Accept.Any(
                         t => t.MediaType.Equals(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeJson, StringComparison.OrdinalIgnoreCase)))
            {
                responseContentType = MediaTypeHeaderValue.Parse(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeJson);
            }

            HttpResponseMessage response = request.CreateResponse(HttpStatusCode.OK);

            response.Content = new ODataBatchContent(responses, requestContainer, responseContentType);
            return(Task.FromResult(response));
        }
Esempio n. 3
0
        /// <inheritdoc/>
        public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
        {
            Type type = context.ObjectType;

            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }
            type = TypeHelper.GetTaskInnerTypeOrSelf(type);

            HttpRequest request = context.HttpContext.Request;

            if (request == null)
            {
                throw Error.InvalidOperation(SRResources.WriteToStreamAsyncMustHaveRequest);
            }

            HttpResponse response = context.HttpContext.Response;

            if (typeof(Stream).IsAssignableFrom(type))
            {
                // Ideally, it should go into the "ODataRawValueSerializer",
                // However, OData lib doesn't provide the method to overwrite/copyto stream
                // So, Here's the workaround
                Stream objStream = context.Object as Stream;
                return(CopyStreamAsync(objStream, response));
            }

            Uri baseAddress = GetBaseAddressInternal(request);
            MediaTypeHeaderValue contentType = GetContentType(response.Headers[HeaderNames.ContentType].FirstOrDefault());

            Func <ODataSerializerContext> getODataSerializerContext = () =>
            {
                return(new ODataSerializerContext()
                {
                    Request = request,
                });
            };

            ODataSerializerProvider serializerProvider = request.GetRequestContainer().GetRequiredService <ODataSerializerProvider>();

            return(ODataOutputFormatterHelper.WriteToStreamAsync(
                       type,
                       context.Object,
                       request.GetModel(),
                       ResultHelpers.GetODataResponseVersion(request),
                       baseAddress,
                       contentType,
                       new WebApiUrlHelper(request.GetUrlHelper()),
                       new WebApiRequestMessage(request),
                       new WebApiRequestHeaders(request.Headers),
                       (services) => ODataMessageWrapperHelper.Create(new StreamWrapper(response.Body), response.Headers, services),
                       (edmType) => serializerProvider.GetEdmTypeSerializer(edmType),
                       (objectType) => serializerProvider.GetODataPayloadSerializer(objectType, request),
                       getODataSerializerContext));
        }
Esempio n. 4
0
        public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
        {
            Type type = context.ObjectType;

            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }
            type = TypeHelper.GetTaskInnerTypeOrSelf(type);

            HttpRequest request = context.HttpContext.Request;

            if (request == null)
            {
                throw Error.InvalidOperation(SRResources.WriteToStreamAsyncMustHaveRequest);
            }

            try
            {
                HttpResponse         response    = context.HttpContext.Response;
                Uri                  baseAddress = GetBaseAddressInternal(request);
                MediaTypeHeaderValue contentType = GetContentType(response.Headers[HeaderNames.ContentType].FirstOrDefault());

                Func <ODataSerializerContext> getODataSerializerContext = () =>
                {
                    return(new ODataSerializerContext()
                    {
                        Request = request,
                    });
                };

                ODataSerializerProvider serializerProvider = request.GetRequestContainer().GetRequiredService <ODataSerializerProvider>();

                ODataOutputFormatterHelper.WriteToStream(
                    type,
                    context.Object,
                    request.GetModel(),
                    ResultHelpers.GetODataResponseVersion(request),
                    baseAddress,
                    contentType,
                    new WebApiUrlHelper(request.GetUrlHelper()),
                    new WebApiRequestMessage(request),
                    new WebApiRequestHeaders(request.Headers),
                    (services) => ODataMessageWrapperHelper.Create(response.Body, response.Headers, services),
                    (edmType) => serializerProvider.GetEdmTypeSerializer(edmType),
                    (objectType) => serializerProvider.GetODataPayloadSerializer(objectType, request),
                    getODataSerializerContext);

                return(TaskHelpers.Completed());
            }
            catch (Exception ex)
            {
                return(TaskHelpers.FromError(ex));
            }
        }
        internal static Task <HttpResponseMessage> CreateODataBatchResponseAsync(this HttpRequestMessage request, IEnumerable <ODataBatchResponseItem> responses, ODataMessageQuotas messageQuotas)
        {
            Contract.Assert(request != null);

            ODataVersion               odataVersion     = ResultHelpers.GetODataResponseVersion(request);
            IServiceProvider           requestContainer = request.GetRequestContainer();
            ODataMessageWriterSettings writerSettings   =
                requestContainer.GetRequiredService <ODataMessageWriterSettings>();

            writerSettings.Version       = odataVersion;
            writerSettings.MessageQuotas = messageQuotas;
            HttpHeaderValueCollection <MediaTypeWithQualityHeaderValue> acceptHeaderValues = request.Headers.Accept;

            MediaTypeHeaderValue responseContentType = null;

            foreach (MediaTypeWithQualityHeaderValue acceptHeader in acceptHeaderValues.OrderByDescending(h => h.Quality == null ? 1 : h.Quality))
            {
                if (acceptHeader.MediaType.Equals(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeMime, StringComparison.OrdinalIgnoreCase))
                {
                    responseContentType = MediaTypeHeaderValue.Parse(
                        String.Format(CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}",
                                      Guid.NewGuid()));
                    break;
                }
                else if (acceptHeader.MediaType.Equals(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeJson, StringComparison.OrdinalIgnoreCase))
                {
                    responseContentType = MediaTypeHeaderValue.Parse(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeJson);
                    break;
                }
            }

            if (responseContentType == null)
            {
                // In absence of accept, if request was JSON then default response to be JSON.
                // Note that, if responseContentType is not set, then it will default to multipart/mixed
                // when constructing the BatchContent, so we don't need to handle that case here
                if (request.Content != null && request.Content.Headers.Any(h => String.Equals(h.Key, ODataBatchHttpRequestMessageExtensions.ContentType, StringComparison.OrdinalIgnoreCase) &&
                                                                           h.Value.Any(v => v.IndexOf(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeJson, StringComparison.OrdinalIgnoreCase) > -1)))
                {
                    responseContentType = MediaTypeHeaderValue.Parse(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeJson);
                }
            }

            HttpResponseMessage response = request.CreateResponse(HttpStatusCode.OK);

            response.Content = new ODataBatchContent(responses, requestContainer, responseContentType);
            return(Task.FromResult(response));
        }
Esempio n. 6
0
        /// <inheritdoc/>
        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            // Determine the content type or let base class handle it.
            MediaTypeHeaderValue newMediaType = null;

            if (ODataOutputFormatterHelper.TryGetContentHeader(type, mediaType, out newMediaType))
            {
                headers.ContentType = newMediaType;
            }
            else
            {
                // This is the case when a user creates a new ObjectContent<T> passing in a null mediaType
                base.SetDefaultContentHeaders(type, headers, mediaType);
            }

            // Set the character set.
            IEnumerable <string> acceptCharsetValues = Request.Headers.AcceptCharset.Select(cs => cs.Value);

            string newCharSet = String.Empty;

            if (ODataOutputFormatterHelper.TryGetCharSet(headers.ContentType, acceptCharsetValues, out newCharSet))
            {
                headers.ContentType.CharSet = newCharSet;
            }

            // Add version header.
            headers.TryAddWithoutValidation(
                ODataVersionConstraint.ODataServiceVersionHeader,
                ODataUtils.ODataVersionToString(ResultHelpers.GetODataResponseVersion(Request)));

            // Add Preference-Applied headers
            var responseMessage = ODataOutputFormatterHelper.PrepareResponseMessage(
                new WebApiRequestMessage(Request),
                new WebApiRequestHeaders(Request.Headers),
                (services) => ODataMessageWrapperHelper.Create(null, headers, services));

            foreach (var header in responseMessage.Headers)
            {
                if (!headers.Contains(header.Key))
                {
                    headers.TryAddWithoutValidation(header.Key, header.Value);
                }
            }
        }
Esempio n. 7
0
        /// <inheritdoc/>
        public override void WriteResponseHeaders(OutputFormatterWriteContext context)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            Type type = context.ObjectType;

            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }
            type = TypeHelper.GetTaskInnerTypeOrSelf(type);

            HttpRequest request = context.HttpContext.Request;

            if (request == null)
            {
                throw Error.InvalidOperation(SRResources.WriteToStreamAsyncMustHaveRequest);
            }

            HttpResponse response = context.HttpContext.Response;

            response.ContentType = context.ContentType.Value;

            MediaTypeHeaderValue contentType = GetContentType(response.Headers[HeaderNames.ContentType].FirstOrDefault());

            // Determine the content type.
            MediaTypeHeaderValue newMediaType = null;

            if (ODataOutputFormatterHelper.TryGetContentHeader(type, contentType, out newMediaType))
            {
                response.Headers[HeaderNames.ContentType] = new StringValues(newMediaType.ToString());
            }

            // Set the character set.
            MediaTypeHeaderValue currentContentType = GetContentType(response.Headers[HeaderNames.ContentType].FirstOrDefault());
            RequestHeaders       requestHeader      = request.GetTypedHeaders();

            if (requestHeader != null && requestHeader.AcceptCharset != null)
            {
                IEnumerable <string> acceptCharsetValues = requestHeader.AcceptCharset.Select(cs => cs.Value.Value);

                string newCharSet = string.Empty;
                if (ODataOutputFormatterHelper.TryGetCharSet(currentContentType, acceptCharsetValues, out newCharSet))
                {
                    currentContentType.CharSet = newCharSet;
                    response.Headers[HeaderNames.ContentType] = new StringValues(currentContentType.ToString());
                }
            }

            // Add version header.
            response.Headers[ODataVersionConstraint.ODataServiceVersionHeader] = ODataUtils.ODataVersionToString(ResultHelpers.GetODataResponseVersion(request));
        }
Esempio n. 8
0
        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content,
                                                TransportContext transportContext, CancellationToken cancellationToken)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }
            if (writeStream == null)
            {
                throw Error.ArgumentNull("writeStream");
            }
            if (Request == null)
            {
                throw Error.InvalidOperation(SRResources.WriteToStreamAsyncMustHaveRequest);
            }
            if (cancellationToken.IsCancellationRequested)
            {
                return(TaskHelpers.Canceled());
            }

            try
            {
                HttpConfiguration configuration = Request.GetConfiguration();
                if (configuration == null)
                {
                    throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration);
                }

                HttpContentHeaders contentHeaders = (content == null) ? null : content.Headers;
                UrlHelper          urlHelper      = Request.GetUrlHelper() ?? new UrlHelper(Request);

                Func <ODataSerializerContext> getODataSerializerContext = () =>
                {
                    return(new ODataSerializerContext()
                    {
                        Request = Request,
                        Url = urlHelper,
                    });
                };

                ODataSerializerProvider serializerProvider = Request.GetRequestContainer()
                                                             .GetRequiredService <ODataSerializerProvider>();

                ODataOutputFormatterHelper.WriteToStream(
                    type,
                    value,
                    Request.GetModel(),
                    ResultHelpers.GetODataResponseVersion(Request),
                    GetBaseAddressInternal(Request),
                    contentHeaders == null ? null : contentHeaders.ContentType,
                    new WebApiUrlHelper(urlHelper),
                    new WebApiRequestMessage(Request),
                    new WebApiRequestHeaders(Request.Headers),
                    (services) => ODataMessageWrapperHelper.Create(writeStream, contentHeaders, services),
                    (edmType) => serializerProvider.GetEdmTypeSerializer(edmType),
                    (objectType) => serializerProvider.GetODataPayloadSerializer(objectType, Request),
                    getODataSerializerContext);

                return(TaskHelpers.Completed());
            }
            catch (Exception ex)
            {
                return(TaskHelpers.FromError(ex));
            }
        }
Esempio n. 9
0
        public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

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

            if (Request == null)
            {
                throw Error.InvalidOperation(SRResources.ReadFromStreamAsyncMustHaveRequest);
            }

            object defaultValue = GetDefaultValueForType(type);

            // If content length is 0 then return default value for this type
            HttpContentHeaders contentHeaders = (content == null) ? null : content.Headers;

            if (contentHeaders == null || contentHeaders.ContentLength == 0)
            {
                return(Task.FromResult(defaultValue));
            }

            try
            {
                Func <ODataDeserializerContext> getODataDeserializerContext = () =>
                {
                    return(new ODataDeserializerContext
                    {
                        Request = Request,
                    });
                };

                Action <Exception> logErrorAction = (ex) =>
                {
                    if (formatterLogger == null)
                    {
                        throw ex;
                    }

                    formatterLogger.LogError(String.Empty, ex);
                };

                ODataDeserializerProvider deserializerProvider = Request.GetRequestContainer()
                                                                 .GetRequiredService <ODataDeserializerProvider>();

                return(Task.FromResult(ODataInputFormatterHelper.ReadFromStream(
                                           type,
                                           defaultValue,
                                           Request.GetModel(),
                                           ResultHelpers.GetODataResponseVersion(Request),
                                           GetBaseAddressInternal(Request),
                                           new WebApiRequestMessage(Request),
                                           () => ODataMessageWrapperHelper.Create(readStream, contentHeaders, Request.GetODataContentIdMapping(), Request.GetRequestContainer()),
                                           (objectType) => deserializerProvider.GetEdmTypeDeserializer(objectType),
                                           (objectType) => deserializerProvider.GetODataDeserializer(objectType, Request),
                                           getODataDeserializerContext,
                                           (disposable) => Request.RegisterForDispose(disposable),
                                           logErrorAction)));
            }
            catch (Exception ex)
            {
                return(TaskHelpers.FromError <object>(ex));
            }
        }