Example #1
0
        public Task SerializeToStreamAsync(Stream stream)
        {
            // how to dispose it?
            IODataResponseMessage responseMessage = ODataMessageWrapperHelper.Create(stream, Headers, _requestContainer);

            return(WriteToResponseMessageAsync(responseMessage));
        }
Example #2
0
        public async Task Posting_NonDerivedType_To_Action_Expecting_BaseType_Throws()
        {
            // Arrange
            StringContent        content      = new StringContent("{ '@odata.type' : '#Microsoft.AspNet.OData.Test.Builder.TestModels.Motorcycle' }");
            var                  headers      = FormatterTestHelper.GetContentHeaders("application/json");
            IODataRequestMessage oDataRequest = ODataMessageWrapperHelper.Create(await content.ReadAsStreamAsync(), headers);
            ODataMessageReader   reader       = new ODataMessageReader(oDataRequest, new ODataMessageReaderSettings(), _model);

            ODataDeserializerProvider deserializerProvider = ODataDeserializerProviderFactory.Create();

            ODataDeserializerContext context = new ODataDeserializerContext {
                Model = _model
            };
            IEdmActionImport action = _model.EntityContainer
                                      .OperationImports()
                                      .Single(f => f.Name == "PostMotorcycle_When_Expecting_Car") as IEdmActionImport;

            Assert.NotNull(action);
            IEdmEntitySetBase actionEntitySet;

            action.TryGetStaticEntitySet(_model, out actionEntitySet);
            context.Path = new ODataPath(new OperationImportSegment(new[] { action }, actionEntitySet, null));

            // Act & Assert
            ExceptionAssert.Throws <ODataException>(
                () => new ODataResourceDeserializer(deserializerProvider).Read(reader, typeof(Car), context),
                "A resource with type 'Microsoft.AspNet.OData.Test.Builder.TestModels.Motorcycle' was found, " +
                "but it is not assignable to the expected type 'Microsoft.AspNet.OData.Test.Builder.TestModels.Car'. " +
                "The type specified in the resource must be equal to either the expected type or a derived type.");
        }
        public async Task WriteMessageAsync_AsynchronouslyWritesResponseMessage()
        {
            // Arrange
            HeaderDictionary headers = new HeaderDictionary
            {
                { "Content-Type", $"multipart/mixed;charset=utf-8;boundary={Guid.NewGuid()}" },
            };
            MemoryStream          ms            = new MemoryStream();
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(ms, headers);

            HeaderDictionary responseHeaders = new HeaderDictionary
            {
                { "customHeader", "bar" }
            };
            HttpResponse response = CreateResponse("example content", responseHeaders, "text/example");

            // Act
            ODataBatchWriter batchWriter = await new ODataMessageWriter(odataResponse).CreateODataBatchWriterAsync();
            await batchWriter.WriteStartBatchAsync();

            await ODataBatchResponseItem.WriteMessageAsync(batchWriter, response.HttpContext);

            await batchWriter.WriteEndBatchAsync();

            ms.Position = 0;
            string result = new StreamReader(ms).ReadToEnd();

            // Assert
            Assert.Contains("example content", result);
            Assert.Contains("text/example", result);
            Assert.Contains("customHeader", result);
            Assert.Contains("bar", result);
        }
Example #4
0
        private static async Task <IODataRequestMessage> CreateRequest(string body)
        {
            HttpContent content = new StringContent(body);
            var         headers = FormatterTestHelper.GetContentHeaders("application/json;odata.metadata=full");

            return(ODataMessageWrapperHelper.Create(await content.ReadAsStreamAsync(), headers));
        }
        public void WriteMessage_SynchronouslyWritesResponseMessage_Throws()
        {
            HeaderDictionary headers = new HeaderDictionary
            {
                { "Content-Type", $"multipart/mixed;charset=utf-8;boundary={Guid.NewGuid()}" },
            };

            MemoryStream          ms            = new MemoryStream();
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(ms, headers);

            HeaderDictionary responseHeaders = new HeaderDictionary
            {
                { "customHeader", "bar" }
            };
            HttpResponse response = CreateResponse("example content", responseHeaders, "text/example");

            // Act
            ODataBatchWriter batchWriter = new ODataMessageWriter(odataResponse).CreateODataBatchWriter();

            batchWriter.WriteStartBatch();

            // Assert
            Action         test      = () => ODataBatchResponseItem.WriteMessageAsync(batchWriter, response.HttpContext).Wait();
            ODataException exception = ExceptionAssert.Throws <ODataException>(test);

            Assert.Equal("An asynchronous operation was called on a synchronous batch writer. Calls on a batch writer instance must be either all synchronous or all asynchronous.",
                         exception.Message);
        }
Example #6
0
        public async Task WriteMessageAsync_WritesResponseMessage()
        {
            MemoryStream ms      = new MemoryStream();
            HttpContent  content = new StringContent(String.Empty, Encoding.UTF8, "multipart/mixed");

            content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundary", Guid.NewGuid().ToString()));
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(ms, content.Headers);
            var batchWriter = new ODataMessageWriter(odataResponse).CreateODataBatchWriter();
            HttpResponseMessage response = new HttpResponseMessage()
            {
                Content = new StringContent("example content", Encoding.UTF8, "text/example")
            };

            response.Headers.Add("customHeader", "bar");

            batchWriter.WriteStartBatch();
            await ODataBatchResponseItem.WriteMessageAsync(batchWriter, response, CancellationToken.None);

            batchWriter.WriteEndBatch();

            ms.Position = 0;
            string result = new StreamReader(ms).ReadToEnd();

            Assert.Contains("example content", result);
            Assert.Contains("text/example", result);
            Assert.Contains("customHeader", result);
            Assert.Contains("bar", result);
        }
Example #7
0
        public async Task WriteMessageAsync_ResponseContainsContentId_IfHasContentIdInRequestChangeSet()
        {
            MemoryStream ms      = new MemoryStream();
            HttpContent  content = new StringContent(String.Empty, Encoding.UTF8, "multipart/mixed");

            content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundary", Guid.NewGuid().ToString()));
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(ms, content.Headers);
            var batchWriter = new ODataMessageWriter(odataResponse).CreateODataBatchWriter();
            HttpResponseMessage response = new HttpResponseMessage
            {
                Content = new StringContent("any", Encoding.UTF8, "text/example")
            };
            var request   = new HttpRequestMessage();
            var contentId = Guid.NewGuid().ToString();

            request.SetODataContentId(contentId);
            response.RequestMessage = request;

            batchWriter.WriteStartBatch();
            batchWriter.WriteStartChangeset();
            await ODataBatchResponseItem.WriteMessageAsync(batchWriter, response, CancellationToken.None);

            batchWriter.WriteEndChangeset();
            batchWriter.WriteEndBatch();

            ms.Position = 0;
            string result = new StreamReader(ms).ReadToEnd();

            Assert.Contains("any", result);
            Assert.Contains("text/example", result);
            Assert.Contains("Content-ID", result);
            Assert.Contains(contentId, result);
        }
        public void WriteMessageAsync_SynchronousResponseContainsContentId_IfHasContentIdInRequestChangeSet()
        {
            // Arrange
            HeaderDictionary headers = new HeaderDictionary
            {
                { "Content-Type", $"multipart/mixed;charset=utf-8;boundary={Guid.NewGuid()}" },
            };

            MemoryStream          ms            = new MemoryStream();
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(ms, headers);

            string       contentId    = Guid.NewGuid().ToString();
            HttpResponse httpResponse = CreateResponse("any", new HeaderDictionary(), "text/example;charset=utf-8");

            httpResponse.HttpContext.Request.SetODataContentId(contentId);

            // Act
            ODataBatchWriter batchWriter = new ODataMessageWriter(odataResponse).CreateODataBatchWriter();

            batchWriter.WriteStartBatch();
            batchWriter.WriteStartChangeset();

            // Assert
            Action         test      = () => ODataBatchResponseItem.WriteMessageAsync(batchWriter, httpResponse.HttpContext).Wait();
            ODataException exception = ExceptionAssert.Throws <ODataException>(test);

            Assert.Equal("An asynchronous operation was called on a synchronous batch writer. Calls on a batch writer instance must be either all synchronous or all asynchronous.",
                         exception.Message);
        }
Example #9
0
        public void ResolveUrl_ReturnsOriginalUri_IfContentIdCannotBeResolved()
        {
            var headers = FormatterTestHelper.GetContentHeaders();
            var message = ODataMessageWrapperHelper.Create(new MemoryStream(), headers);

            Uri uri = message.ConvertPayloadUri(new Uri("http://localhost"), new Uri("$1", UriKind.Relative));

            Assert.Equal("$1", uri.OriginalString);
        }
Example #10
0
        public async Task ExecuteChangeSetAsync_CopiesPropertiesFromRequest_WithoutExcludedProperties()
        {
            // Arrange
            RequestDelegate handler = context =>
            {
                context.Features[typeof(UnbufferedODataBatchHandlerTest)] = "bar";
                return(Task.FromResult(context.Response));
            };

            UnbufferedODataBatchHandler batchHandler = new UnbufferedODataBatchHandler();

            string      batchRequest = @"--cb7bb9ee-dce2-4c94-bf11-b742b2bc6072
Content-Type: multipart/mixed; boundary=""09f27d33-41ea-4334-8ace-1738bd2793a9""

--09f27d33-41ea-4334-8ace-1738bd2793a9
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1328966982

POST /values HTTP/1.1
Host: example.com
Content-Type: text/plain; charset=utf-8

foo
--09f27d33-41ea-4334-8ace-1738bd2793a9--

--cb7bb9ee-dce2-4c94-bf11-b742b2bc6072--
";
            HttpRequest request      = RequestFactory.Create("Post", "http://example.com/$batch", opt => opt.AddModel(EdmCoreModel.Instance));
            HttpContext httpContext  = request.HttpContext;

            byte[] requestBytes = Encoding.UTF8.GetBytes(batchRequest);
            request.Body          = new MemoryStream(requestBytes);
            request.ContentType   = "multipart/mixed;boundary=\"09f27d33-41ea-4334-8ace-1738bd2793a9\"";
            request.ContentLength = 431;
            httpContext.ODataFeature().PrefixName = "";
            IServiceProvider sp = request.GetSubServiceProvider();

            IODataRequestMessage oDataRequestMessage = ODataMessageWrapperHelper.Create(request.Body, request.Headers, sp);
            ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, new ODataMessageReaderSettings {
                BaseUri = new Uri("http://example.com")
            });

            ODataBatchReader batchReader = await oDataMessageReader.CreateODataBatchReaderAsync();

            List <ODataBatchResponseItem> responses = new List <ODataBatchResponseItem>();

            // Act
            var response = await batchHandler.ExecuteChangeSetAsync(batchReader, Guid.NewGuid(), request, handler);

            // Arrange
            ChangeSetResponseItem changeSetResponseItem = Assert.IsType <ChangeSetResponseItem>(response);
            HttpContext           changeSetContext      = Assert.Single(changeSetResponseItem.Contexts);

            Assert.Equal("bar", changeSetContext.Features[typeof(UnbufferedODataBatchHandlerTest)]);
        }
Example #11
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));
        }
Example #12
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));
            }
        }
Example #13
0
        private static IODataRequestMessage CreateRequest()
        {
            //HttpContentHeaders headers;
            //using (HttpContent content = new StreamContent(Stream.Null))
            //{
            //    headers = content.Headers;
            //}

            var headers = FormatterTestHelper.GetContentHeaders("application/json;odata.metadata=full");

            return(ODataMessageWrapperHelper.Create(Stream.Null, headers));
        }
Example #14
0
        public async Task WriteMessageAsync_NullResponse_Throws()
        {
            HttpContent content = new StringContent(String.Empty, Encoding.UTF8, "multipart/mixed");

            content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundary", Guid.NewGuid().ToString()));
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(new MemoryStream(), content.Headers);
            ODataMessageWriter    messageWriter = new ODataMessageWriter(odataResponse);

            await ExceptionAssert.ThrowsArgumentNullAsync(
                () => ODataBatchResponseItem.WriteMessageAsync(messageWriter.CreateODataBatchWriter(), null, CancellationToken.None),
                "response");
        }
        /// <summary>
        /// Gets the <see cref="ODataMessageReader"/> for the <see cref="HttpRequest"/> stream.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="requestContainer">The dependency injection container for the request.</param>
        /// <returns>A task object that produces an <see cref="ODataMessageReader"/> when completed.</returns>
        public static ODataMessageReader GetODataMessageReader(this HttpRequest request, IServiceProvider requestContainer)
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            IODataRequestMessage       oDataRequestMessage = ODataMessageWrapperHelper.Create(request.Body, request.Headers, requestContainer);
            ODataMessageReaderSettings settings            = requestContainer.GetRequiredService <ODataMessageReaderSettings>();
            ODataMessageReader         oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, settings);

            return(oDataMessageReader);
        }
        public async Task WriteMessageAsync_NullContext_Throws()
        {
            // Arrange
            HeaderDictionary headers = new HeaderDictionary
            {
                { "Content-Type", $"multipart/mixed;charset=utf-8;boundary={Guid.NewGuid()}" },
            };
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(new MemoryStream(), headers);
            ODataMessageWriter    messageWriter = new ODataMessageWriter(odataResponse);

            // Act & Assert
            await ExceptionAssert.ThrowsArgumentNullAsync(
                () => ODataBatchResponseItem.WriteMessageAsync(messageWriter.CreateODataBatchWriter(), null), "context");
        }
Example #17
0
        public async Task ExecuteOperationAsync_CopiesPropertiesFromRequest_WithoutExcludedProperties()
        {
            // Arrange
            RequestDelegate handler = context =>
            {
                context.Features[typeof(UnbufferedODataBatchHandlerTest)] = "foo";
                return(Task.FromResult(context.Response));
            };

            UnbufferedODataBatchHandler batchHandler = new UnbufferedODataBatchHandler();
            string batchRequest = @"--75148e61-e67a-4bb7-ac0f-78fa30d0da30
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 318941389

GET / HTTP/1.1
Host: example.com


--75148e61-e67a-4bb7-ac0f-78fa30d0da30--
";

            HttpRequest request     = RequestFactory.Create("Post", "http://example.com/$batch", opt => opt.AddModel(EdmCoreModel.Instance));
            HttpContext httpContext = request.HttpContext;

            byte[] requestBytes = Encoding.UTF8.GetBytes(batchRequest);
            request.Body          = new MemoryStream(requestBytes);
            request.ContentType   = "multipart/mixed;boundary=\"75148e61-e67a-4bb7-ac0f-78fa30d0da30\"";
            request.ContentLength = 431;
            httpContext.ODataFeature().PrefixName = "";
            IServiceProvider sp = request.GetSubServiceProvider();

            IODataRequestMessage oDataRequestMessage = ODataMessageWrapperHelper.Create(httpContext.Request.Body, request.Headers, sp);
            ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, new ODataMessageReaderSettings {
                BaseUri = new Uri("http://example.com")
            });

            ODataBatchReader batchReader = await oDataMessageReader.CreateODataBatchReaderAsync();

            List <ODataBatchResponseItem> responses = new List <ODataBatchResponseItem>();
            await batchReader.ReadAsync();

            // Act
            var response = await batchHandler.ExecuteOperationAsync(batchReader, Guid.NewGuid(), httpContext.Request, handler);

            // Assert
            OperationResponseItem operationResponseItem = Assert.IsType <OperationResponseItem>(response);

            Assert.Equal("foo", operationResponseItem.Context.Features[typeof(UnbufferedODataBatchHandlerTest)]);
        }
Example #18
0
        public static ODataMessageReader GetODataMessageReader(this HttpRequest request, IServiceProvider requestContainer)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            // how to dispose it?
            IODataRequestMessage       oDataRequestMessage = ODataMessageWrapperHelper.Create(request.Body, request.Headers, requestContainer);
            ODataMessageReaderSettings settings            = requestContainer.GetRequiredService <ODataMessageReaderSettings>();
            ODataMessageReader         oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, settings);

            return(oDataMessageReader);
        }
Example #19
0
        public void ResolveUrl_ResolvesUriWithContentId()
        {
            Dictionary <string, string> contentIdMapping = new Dictionary <string, string>
            {
                { "1", "http://localhost/values(1)" },
                { "11", "http://localhost/values(11)" },
            };

            var headers = FormatterTestHelper.GetContentHeaders();
            var message = ODataMessageWrapperHelper.Create(new MemoryStream(), headers, contentIdMapping);

            Uri uri = message.ConvertPayloadUri(new Uri("http://localhost"), new Uri("$1", UriKind.Relative));

            Assert.Equal("http://localhost/values(1)", uri.OriginalString);
        }
Example #20
0
        /// <summary>
        /// Gets the <see cref="ODataMessageReader"/> for the <see cref="HttpContent"/> stream.
        /// </summary>
        /// <param name="content">The <see cref="HttpContent"/>.</param>
        /// <param name="settings">The <see cref="ODataMessageReaderSettings"/>.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <returns>A task object that produces an <see cref="ODataMessageReader"/> when completed.</returns>
        public static async Task <ODataMessageReader> GetODataMessageReaderAsync(this HttpContent content,
                                                                                 ODataMessageReaderSettings settings, CancellationToken cancellationToken)
        {
            if (content == null)
            {
                throw Error.ArgumentNull("content");
            }

            cancellationToken.ThrowIfCancellationRequested();
            Stream contentStream = await content.ReadAsStreamAsync();

            IODataRequestMessage oDataRequestMessage = ODataMessageWrapperHelper.Create(contentStream, content.Headers, new MockContainer());
            ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, settings);

            return(oDataMessageReader);
        }
        private ODataMessageWriter GetODataMessageWriter(IEdmModel model, MemoryStream bufferedStream)
        {
            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
            {
                BaseUri  = new Uri("http://localhost/odata"),
                Version  = ODataVersion.V4,
                ODataUri = new ODataUri {
                    ServiceRoot = new Uri("http://localhost/odata")
                }
            };

            var headers = FormatterTestHelper.GetContentHeaders("application/json");
            IODataResponseMessage responseMessage = ODataMessageWrapperHelper.Create(bufferedStream, headers);

            return(new ODataMessageWriter(responseMessage, writerSettings, model));
        }
Example #22
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);
                }
            }
        }
Example #23
0
        public async Task ReadAsync_ReturnsEdmComplexObjectCollection_TypelessMode()
        {
            // Arrange
            IEdmTypeReference           addressType           = _model.GetEdmTypeReference(typeof(Address)).AsComplex();
            IEdmCollectionTypeReference addressCollectionType =
                new EdmCollectionTypeReference(new EdmCollectionType(addressType));

            HttpContent      content    = new StringContent("{ 'value': [ {'@odata.type':'Microsoft.AspNetCore.OData.Tests.Models.Address', 'City' : 'Redmond' } ] }");
            HeaderDictionary headerDict = new HeaderDictionary
            {
                { "Content-Type", "application/json" }
            };

            IODataRequestMessage request         = ODataMessageWrapperHelper.Create(await content.ReadAsStreamAsync(), headerDict);
            ODataMessageReader   reader          = new ODataMessageReader(request, new ODataMessageReaderSettings(), _model);
            var deserializer                     = new ODataResourceSetDeserializer(_deserializerProvider);
            ODataDeserializerContext readContext = new ODataDeserializerContext
            {
                Model           = _model,
                ResourceType    = typeof(IEdmObject),
                ResourceEdmType = addressCollectionType
            };

            // Act
            IEnumerable result = await deserializer.ReadAsync(reader, typeof(IEdmObject), readContext) as IEnumerable;

            // Assert
            var addresses = result.Cast <EdmComplexObject>();

            Assert.NotNull(addresses);

            EdmComplexObject address = Assert.Single(addresses);

            Assert.Equal(new[] { "City" }, address.GetChangedPropertyNames());

            object city;

            Assert.True(address.TryGetPropertyValue("City", out city));
            Assert.Equal("Redmond", city);
        }
Example #24
0
        /// <summary>
        /// Gets the <see cref="ODataMessageReader"/> for the <see cref="HttpContent"/> stream.
        /// </summary>
        /// <param name="content">The <see cref="HttpContent"/>.</param>
        /// <param name="settings">The <see cref="ODataMessageReaderSettings"/>.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <returns>A task object that produces an <see cref="ODataMessageReader"/> when completed.</returns>
        public static async Task <ODataMessageReader> GetODataMessageReaderAsync(this HttpContent content,
                                                                                 ODataMessageReaderSettings settings, CancellationToken cancellationToken)
        {
            if (content == null)
            {
                throw Error.ArgumentNull("content");
            }

            cancellationToken.ThrowIfCancellationRequested();
            Stream contentStream = await content.ReadAsStreamAsync();

            HeaderDictionary headerDict = new HeaderDictionary();

            foreach (var head in content.Headers)
            {
                headerDict[head.Key] = new StringValues(head.Value.ToArray());
            }

            IODataRequestMessage oDataRequestMessage = ODataMessageWrapperHelper.Create(contentStream, headerDict /*, new MockServiceProvider()*/);
            ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, settings);

            return(oDataMessageReader);
        }
        public async Task WriteMessageAsync_ResponseContainsContentId_IfHasContentIdInRequestChangeSet()
        {
            // Arrange
            HeaderDictionary headers = new HeaderDictionary
            {
                { "Content-Type", $"multipart/mixed;charset=utf-8;boundary={Guid.NewGuid()}" },
            };

            MemoryStream          ms            = new MemoryStream();
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(ms, headers);

            string       contentId    = Guid.NewGuid().ToString();
            HttpResponse httpResponse = CreateResponse("any", new HeaderDictionary(), "text/example;charset=utf-8");

            httpResponse.HttpContext.Request.SetODataContentId(contentId);

            // Act
            ODataBatchWriter batchWriter = await new ODataMessageWriter(odataResponse).CreateODataBatchWriterAsync();
            await batchWriter.WriteStartBatchAsync();

            await batchWriter.WriteStartChangesetAsync();

            await ODataBatchResponseItem.WriteMessageAsync(batchWriter, httpResponse.HttpContext);

            await batchWriter.WriteEndChangesetAsync();

            await batchWriter.WriteEndBatchAsync();

            ms.Position = 0;
            string result = new StreamReader(ms).ReadToEnd();

            // Assert
            Assert.Contains("any", result);
            Assert.Contains("text/example", result);
            Assert.Contains("Content-ID", result);
            Assert.Contains(contentId, result);
        }
Example #26
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));
            }
        }
Example #27
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(),
                                           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));
            }
        }
Example #28
0
        public async Task ExecuteChangeSetAsync_ReturnsSingleErrorResponse()
        {
            // Arrange
            RequestDelegate handler = context =>
            {
                if (context.Request.Method.ToUpperInvariant() == "POST")
                {
                    context.Response.StatusCode = StatusCodes.Status400BadRequest;
                    return(Task.FromResult(context.Response));
                }

                return(Task.FromResult(context.Response));
            };

            UnbufferedODataBatchHandler batchHandler = new UnbufferedODataBatchHandler();
            string batchRequest = @"--86aef3eb-4af6-4750-a66d-df65e3f31ab0
Content-Type: multipart/mixed; boundary=""7a61b8c1-a80e-4e6b-bac7-2f65564e3fd6""

--7a61b8c1-a80e-4e6b-bac7-2f65564e3fd6
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: -1233709575

PUT /values HTTP/1.1
Host: example.com


--7a61b8c1-a80e-4e6b-bac7-2f65564e3fd6
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: -1854117385

POST /values HTTP/1.1
Host: example.com


--7a61b8c1-a80e-4e6b-bac7-2f65564e3fd6
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: -1665098746

DELETE /values HTTP/1.1
Host: example.com


--7a61b8c1-a80e-4e6b-bac7-2f65564e3fd6--

--86aef3eb-4af6-4750-a66d-df65e3f31ab0--";

            IEdmModel   model       = new EdmModel();
            HttpRequest request     = RequestFactory.Create("Post", "http://example.com/$batch", opt => opt.AddModel(model));
            HttpContext httpContext = request.HttpContext;

            byte[] requestBytes = Encoding.UTF8.GetBytes(batchRequest);
            httpContext.Request.Body          = new MemoryStream(requestBytes);
            httpContext.Request.ContentType   = "multipart/mixed;boundary=\"86aef3eb-4af6-4750-a66d-df65e3f31ab0\"";
            httpContext.Request.ContentLength = 431;
            httpContext.ODataFeature().PrefixName = "";
            IServiceProvider sp = request.GetSubServiceProvider();

            IODataRequestMessage oDataRequestMessage = ODataMessageWrapperHelper.Create(httpContext.Request.Body, request.Headers, sp);
            ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, new ODataMessageReaderSettings {
                BaseUri = new Uri("http://example.com")
            });

            ODataBatchReader batchReader = await oDataMessageReader.CreateODataBatchReaderAsync();

            // Act
            var response = await batchHandler.ExecuteChangeSetAsync(batchReader, Guid.NewGuid(), httpContext.Request, handler);

            // Assert
            var changesetResponse = Assert.IsType <ChangeSetResponseItem>(response);
            var returnContext     = Assert.Single(changesetResponse.Contexts);

            Assert.Equal(StatusCodes.Status400BadRequest, returnContext.Response.StatusCode);
        }
Example #29
0
        public override async Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            Type type = context.ModelType;

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

            HttpRequest request = context.HttpContext.Request;

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

            // If content length is 0 then return default value for this type
            RequestHeaders contentHeaders = request.GetTypedHeaders();
            object         defaultValue   = GetDefaultValueForType(type);

            if (contentHeaders == null || contentHeaders.ContentLength == 0)
            {
                return(InputFormatterResult.Success(defaultValue));
            }

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

                Action <Exception> logErrorAction = (ex) =>
                {
                    ILogger logger = context.HttpContext.RequestServices.GetService <ILogger>();
                    if (logger == null)
                    {
                        throw ex;
                    }

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

                List <IDisposable> toDispose = new List <IDisposable>();

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

                object result = await ODataInputFormatterHelper.ReadFromStreamAsync(
                    type,
                    defaultValue,
                    request.GetModel(),
                    GetBaseAddressInternal(request),
                    new WebApiRequestMessage(request),
                    () => ODataMessageWrapperHelper.Create(new StreamWrapper(request.Body), request.Headers, request.GetODataContentIdMapping(), request.GetRequestContainer()),
                    (objectType) => deserializerProvider.GetEdmTypeDeserializer(objectType),
                    (objectType) => deserializerProvider.GetODataDeserializer(objectType, request),
                    getODataDeserializerContext,
                    (disposable) => toDispose.Add(disposable),
                    logErrorAction);

                foreach (IDisposable obj in toDispose)
                {
                    obj.Dispose();
                }

                return(InputFormatterResult.Success(result));
            }
            catch (Exception ex)
            {
                context.ModelState.AddModelError(context.ModelName, ex, context.Metadata);
                return(InputFormatterResult.Failure());
            }
        }
        /// <inheritdoc/>
        /// <remarks>This function uses types that are AspNet-specific.</remarks>
        protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            IODataResponseMessage responseMessage = ODataMessageWrapperHelper.Create(stream, this.Headers, _requestContainer);

            return(WriteToResponseMessageAsync(responseMessage));
        }