Пример #1
0
        internal static Task CreateODataBatchResponseAsync(this HttpRequest request, IEnumerable <ODataBatchResponseItem> responses, ODataMessageQuotas messageQuotas)
        {
            Contract.Assert(request != null);

            ODataVersion odataVersion = ODataInputFormatter.GetODataResponseVersion(request);

            IServiceProvider           requestContainer = request.GetRequestContainer();
            ODataMessageWriterSettings writerSettings   = requestContainer.GetRequiredService <ODataMessageWriterSettings>();

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

            HttpResponse response = request.HttpContext.Response;

            response.StatusCode = (int)HttpStatusCode.OK;

            // Need to get the stream from ODataBatchContent.
            // maybe use the shared class to define bahaviour and put
            // HttpContent and public stream getter in platform-specific?
            ODataBatchContent batchContent = new ODataBatchContent(responses, requestContainer);

            foreach (var header in batchContent.Headers)
            {
                // Copy headers from batch content, overwriting any existing headers.
                response.Headers[header.Key] = header.Value;
            }

            return(batchContent.SerializeToStreamAsync(response.Body));
        }
        public async Task ReadRequestBodyAsyncReturnsDefaultTypeValueWhenContentLengthIsZero <T>(T value)
        {
            // Arrange
            ODataInputFormatter formatter = GetInputFormatter();

            byte[]      contentBytes = Encoding.UTF8.GetBytes("");
            HttpContext httpContext  = GetHttpContext(contentBytes);

            InputFormatterContext formatterContext = CreateInputFormatterContext(typeof(T), httpContext);

            // Act
            InputFormatterResult result = await formatter.ReadRequestBodyAsync(formatterContext, Encoding.UTF8);

            // Assert
            Assert.False(result.HasError);
            Type valueType = value.GetType();

            if (valueType.IsValueType)
            {
                T actualResult = Assert.IsType <T>(result.Model);
                Assert.Equal(default(T), actualResult);
            }
            else
            {
                Assert.Null(result.Model);
            }
        }
Пример #3
0
        public Task ReadRequestBodyAsyncReadsDataButDoesNotCloseStreamWhenContentLengthIsNull()
        {
            // Arrange
            byte[] expectedSampleTypeByte = Encoding.UTF8.GetBytes(
                "{" +
                "\"@odata.context\":\"http://localhost/$metadata#Customers/$entity\"," +
                "\"Number\":42" +
                "}");

            ODataInputFormatter formatter = GetInputFormatter();

            HttpContext httpContext = GetHttpContext(expectedSampleTypeByte);

            httpContext.Request.ContentType   = "application/json;odata.metadata=minimal";
            httpContext.Request.ContentLength = null;
            Stream memStream = httpContext.Request.Body;

            InputFormatterContext formatterContext = CreateInputFormatterContext(typeof(Customer), httpContext);

            // Act
            return(formatter.ReadRequestBodyAsync(formatterContext, Encoding.UTF8).ContinueWith(
                       readTask =>
            {
                // Assert
                Assert.Equal(TaskStatus.RanToCompletion, readTask.Status);
                Assert.True(memStream.CanRead);

                InputFormatterResult result = Assert.IsType <InputFormatterResult>(readTask.Result);
                Assert.Null(result.Model);
            }));
        }
Пример #4
0
        public void CanReadThrowsIfContextIsNull()
        {
            // Arrange & Act
            ODataInputFormatter formatter = new ODataInputFormatter(new[] { ODataPayloadKind.Resource });

            // Assert
            Assert.Throws <ArgumentNullException>("context", () => formatter.CanRead(context: null));
        }
Пример #5
0
        internal static ODataInputFormatter GetInputFormatter(ODataPayloadKind[] payload, HttpRequest request, string mediaType = null)
        {
            ODataInputFormatter inputFormatter = new ODataInputFormatter(payload);

            inputFormatter.SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true));
            inputFormatter.SupportedEncodings.Add(new UnicodeEncoding(bigEndian: false, byteOrderMark: true, throwOnInvalidBytes: true));
            return(inputFormatter);
        }
Пример #6
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            ODataInputFormatter formatter = new ODataInputFormatter(new[] { ODataPayloadKind.Resource });

            app.UseOData(GetEdmModel());
        }
        private static bool CanReadType(ODataInputFormatter formatter, Type type, HttpRequest request)
        {
            InputFormatterContext context = new InputFormatterContext(
                request.HttpContext,
                "modelName",
                new ModelStateDictionary(),
                new EmptyModelMetadataProvider().GetMetadataForType(type),
                (stream, encoding) => new StreamReader(stream, encoding));

            return(formatter.CanRead(context));
        }
Пример #8
0
        internal static Task CreateODataBatchResponseAsync(this HttpRequest request, IEnumerable <ODataBatchResponseItem> responses, ODataMessageQuotas messageQuotas)
        {
            Contract.Assert(request != null);

            ODataVersion odataVersion = ODataInputFormatter.GetODataResponseVersion(request);

            IServiceProvider           requestContainer = request.GetRequestContainer();
            ODataMessageWriterSettings writerSettings   = requestContainer.GetRequiredService <ODataMessageWriterSettings>();

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

            HttpResponse response = request.HttpContext.Response;

            IEnumerable <MediaTypeHeaderValue> acceptHeaders = MediaTypeHeaderValue.ParseList(request.Headers.GetCommaSeparatedValues("Accept"));
            string responseContentType = null;

            foreach (MediaTypeHeaderValue acceptHeader in acceptHeaders.OrderByDescending(h => h.Quality == null ? 1 : h.Quality))
            {
                if (acceptHeader.MediaType.Equals(ODataBatchHttpRequestExtensions.BatchMediaTypeMime, StringComparison.OrdinalIgnoreCase))
                {
                    responseContentType = String.Format(CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}", Guid.NewGuid());
                    break;
                }
                else if (acceptHeader.MediaType.Equals(ODataBatchHttpRequestExtensions.BatchMediaTypeJson, StringComparison.OrdinalIgnoreCase))
                {
                    responseContentType = ODataBatchHttpRequestExtensions.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 (!String.IsNullOrEmpty(request.ContentType) &&
                    request.ContentType.IndexOf(ODataBatchHttpRequestExtensions.BatchMediaTypeJson, StringComparison.OrdinalIgnoreCase) > -1)
                {
                    responseContentType = ODataBatchHttpRequestExtensions.BatchMediaTypeJson;
                }
            }

            response.StatusCode = (int)HttpStatusCode.OK;
            ODataBatchContent batchContent = new ODataBatchContent(responses, requestContainer, responseContentType);

            foreach (var header in batchContent.Headers)
            {
                // Copy headers from batch content, overwriting any existing headers.
                response.Headers[header.Key] = header.Value;
            }

            return(batchContent.SerializeToStreamAsync(response.Body));
        }
Пример #9
0
        public void CanReadReturnsFalseIfNoODataPathSet()
        {
            // Arrange & Act
            InputFormatterContext context = new InputFormatterContext(
                new DefaultHttpContext(),
                "modelName",
                new ModelStateDictionary(),
                new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)),
                (stream, encoding) => new StreamReader(stream, encoding));

            ODataInputFormatter formatter = new ODataInputFormatter(new[] { ODataPayloadKind.Resource });

            // Assert
            Assert.False(formatter.CanRead(context));
        }
Пример #10
0
        public void GetSupportedContentTypesODataInputFormatter_WorksForContentType()
        {
            // Arrange
            ODataInputFormatter formatter = ODataInputFormatterFactory.Create().First();

            Assert.NotNull(formatter); // guard

            // Act & Assert
            IReadOnlyList <string> contentTypes = formatter.GetSupportedContentTypes("application/json", typeof(string));

            Assert.Equal(12, contentTypes.Count);

            // Act & Assert
            formatter.SupportedMediaTypes.Clear();
            ExceptionAssert.DoesNotThrow(() => formatter.GetSupportedContentTypes("application/json", typeof(string)));
        }
Пример #11
0
        public async Task ReadRequestBodyAsyncFailsWhenContentLengthIsZero(Type type)
        {
            // Arrange
            ODataInputFormatter formatter = GetInputFormatter();

            byte[]      contentBytes = Encoding.UTF8.GetBytes("");
            HttpContext httpContext  = GetHttpContext(contentBytes);

            InputFormatterContext formatterContext = CreateInputFormatterContext(type, httpContext);

            // Act
            InputFormatterResult result = await formatter.ReadRequestBodyAsync(formatterContext, Encoding.UTF8);

            // Assert
            Assert.True(result.HasError);
        }
Пример #12
0
        public void CanReadResultODataOutputFormatter_Throws_IfRequestIsNull()
        {
            // Arrange & Act
            ODataInputFormatter formatter   = new ODataInputFormatter(new[] { ODataPayloadKind.Resource });
            Mock <HttpContext>  httpContext = new Mock <HttpContext>();

            httpContext.Setup(c => c.Request).Returns((HttpRequest)null);
            InputFormatterContext context = new InputFormatterContext(httpContext.Object,
                                                                      "any",
                                                                      new ModelStateDictionary(),
                                                                      new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)),
                                                                      (stream, encoding) => null);

            // Assert
            ExceptionAssert.Throws <InvalidOperationException>(
                () => formatter.CanRead(context),
                "The OData formatter requires an attached request in order to deserialize.");
        }
Пример #13
0
        public void CanReadReturnsBooleanValueAsExpected(Type type, ODataPayloadKind payloadKind, bool expected)
        {
            // Arrange & Act
            IEdmEntitySet    entitySet    = _edmModel.EntityContainer.FindEntitySet("Customers");
            EntitySetSegment entitySetSeg = new EntitySetSegment(entitySet);
            HttpRequest      request      = RequestFactory.Create(opt => opt.AddModel("odata", _edmModel));

            request.ODataFeature().PrefixName = "odata";
            request.ODataFeature().Model      = _edmModel;
            request.ODataFeature().Path       = new ODataPath(entitySetSeg);

            InputFormatterContext context = CreateInputContext(type, request);

            ODataInputFormatter formatter = new ODataInputFormatter(new[] { payloadKind });

            // Assert
            Assert.Equal(expected, formatter.CanRead(context));
        }
Пример #14
0
        public async Task ReadRequestBodyAsync_ThrowsArgumentNull_ForInputParameter()
        {
            // Arrange
            ODataInputFormatter   formatter        = GetInputFormatter();
            InputFormatterContext formatterContext = null;

            // Act & Assert
            await ExceptionAssert.ThrowsArgumentNullAsync(() => formatter.ReadRequestBodyAsync(formatterContext, Encoding.UTF8), "context");

            //Mock<ModelMetadata> mock = new Mock<ModelMetadata>();
            //mock.Setup(s => s.ModelType).Returns((Type)null);
            //formatterContext = new InputFormatterContext(new DefaultHttpContext(),
            //    modelName: string.Empty,
            //    modelState: new ModelStateDictionary(),
            //    metadata: mock.Object,
            //    readerFactory: (stream, encoding) => new StreamReader(stream, encoding));

            //await ExceptionAssert.ThrowsArgumentNullAsync(() => formatter.ReadRequestBodyAsync(formatterContext, Encoding.UTF8), "type");
        }
Пример #15
0
        public Task ReadFromStreamAsyncDoesNotCloseStreamWhenContentLengthIsZero()
        {
            // Arrange
            ODataInputFormatter formatter  = GetInputFormatter();
            Mock <Stream>       mockStream = new Mock <Stream>();

            byte[]                contentBytes     = Encoding.UTF8.GetBytes(string.Empty);
            HttpContext           httpContext      = GetHttpContext(contentBytes);
            InputFormatterContext formatterContext = CreateInputFormatterContext(typeof(Customer), httpContext);

            // Act
            return(formatter.ReadRequestBodyAsync(formatterContext, Encoding.UTF8)
                   .ContinueWith(
                       readTask =>
            {
                // Assert
                Assert.Equal(TaskStatus.RanToCompletion, readTask.Status);
                mockStream.Verify(s => s.Close(), Times.Never());
            }));
        }
Пример #16
0
        public void InputFormatsSkipsOfOdataFormatExists()
        {
            var builder = new WebHostBuilder()
                          .UseStartup <TestStartup>();

            TestServer testServer = new TestServer(builder);

            var options    = testServer.Host.Services.GetRequiredService <IConfigureOptions <MvcOptions> >();
            var mvcOptions = new MvcOptions();

            var format = new ODataInputFormatter(new List <ODataPayloadKind>());

            format.SupportedMediaTypes.Add(new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("text/plain"));
            mvcOptions.InputFormatters.Add(format);

            options.Configure(mvcOptions);

            var formater = (ODataInputFormatter)mvcOptions.InputFormatters.First();

            Assert.AreEqual(1, formater.SupportedMediaTypes.Count());
            Assert.AreEqual("text/plain", formater.SupportedMediaTypes[0].ToString());
        }
        public Task ReadRequestBodyAsyncReadsDataButDoesNotCloseStreamWhenContentLengthl()
        {
            // Arrange
            byte[] expectedSampleTypeByte = Encoding.UTF8.GetBytes(
                "{" +
                "\"@odata.context\":\"http://localhost/$metadata#Customers/$entity\"," +
                "\"Number\":42" +
                "}");

            IEdmSingleton    singleton    = _edmModel.EntityContainer.FindSingleton("Me");
            SingletonSegment singletonSeg = new SingletonSegment(singleton);

            ODataInputFormatter formatter = GetInputFormatter();

            formatter.BaseAddressFactory = (request) => new Uri("http://localhost");

            HttpContext httpContext = GetHttpContext(expectedSampleTypeByte, opt => opt.AddModel("odata", _edmModel));

            httpContext.Request.ContentType   = "application/json;odata.metadata=minimal";
            httpContext.Request.ContentLength = expectedSampleTypeByte.Length;
            httpContext.ODataFeature().Model      = _edmModel;
            httpContext.ODataFeature().PrefixName = "odata";
            httpContext.ODataFeature().Path       = new ODataPath(singletonSeg);
            Stream memStream = httpContext.Request.Body;

            InputFormatterContext formatterContext = CreateInputFormatterContext(typeof(Customer), httpContext);

            // Act
            return(formatter.ReadRequestBodyAsync(formatterContext, Encoding.UTF8).ContinueWith(
                       readTask =>
            {
                // Assert
                Assert.Equal(TaskStatus.RanToCompletion, readTask.Status);
                Assert.True(memStream.CanRead);

                var value = Assert.IsType <Customer>(readTask.Result.Model);
                Assert.Equal(42, value.Number);
            }));
        }
        internal static Task CreateODataBatchResponseAsync(this HttpRequest request, IEnumerable <ODataBatchResponseItem> responses, ODataMessageQuotas messageQuotas)
        {
            Contract.Assert(request != null);

            ODataVersion odataVersion = ODataInputFormatter.GetODataResponseVersion(request);

            IServiceProvider           requestContainer = request.GetRequestContainer();
            ODataMessageWriterSettings writerSettings   = requestContainer.GetRequiredService <ODataMessageWriterSettings>();

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

            HttpResponse response = request.HttpContext.Response;

            StringValues acceptHeader = request.Headers["Accept"];
            string       contentType  = null;

            if (StringValues.IsNullOrEmpty(acceptHeader) ||
                acceptHeader.Any(h => h.Equals(ODataBatchHttpRequestExtensions.BatchMediaTypeMime, StringComparison.OrdinalIgnoreCase)))
            {
                contentType = String.Format(CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}", Guid.NewGuid());
            }
            else if (acceptHeader.Any(h => h.Equals(ODataBatchHttpRequestExtensions.BatchMediaTypeJson, StringComparison.OrdinalIgnoreCase)))
            {
                contentType = ODataBatchHttpRequestExtensions.BatchMediaTypeJson;
            }

            response.StatusCode = (int)HttpStatusCode.OK;
            ODataBatchContent batchContent = new ODataBatchContent(responses, requestContainer, contentType);

            foreach (var header in batchContent.Headers)
            {
                // Copy headers from batch content, overwriting any existing headers.
                response.Headers[header.Key] = header.Value;
            }

            return(batchContent.SerializeToStreamAsync(response.Body));
        }
Пример #19
0
        internal static async Task <object> ReadAsync(ODataInputFormatter formatter, string entity, Type valueType, HttpRequest request, string mediaType)
        {
            StringContent content = new StringContent(entity);

            content.Headers.ContentType = MediaTypeHeaderValue.Parse(mediaType);

            Stream stream = await content.ReadAsStreamAsync();

            Func <Stream, Encoding, TextReader> readerFactor = (s, e) =>
            {
                return(new StreamReader(stream));
            };

            request.Body = stream;

            ModelStateDictionary   modelState = new ModelStateDictionary();
            IModelMetadataProvider provider   = request.HttpContext.RequestServices.GetService <IModelMetadataProvider>();
            ModelMetadata          metaData   = provider.GetMetadataForType(valueType);
            InputFormatterContext  context    = new InputFormatterContext(request.HttpContext, "Any", modelState, metaData, readerFactor);

            InputFormatterResult result = await formatter.ReadAsync(context);

            return(result.Model);
        }
Пример #20
0
 public void GetDefaultBaseAddress_ThrowsArgumentNull_Request()
 {
     ExceptionAssert.ThrowsArgumentNull(() => ODataInputFormatter.GetDefaultBaseAddress(null), "request");
 }