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); } }
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); })); }
public void CanReadThrowsIfContextIsNull() { // Arrange & Act ODataInputFormatter formatter = new ODataInputFormatter(new[] { ODataPayloadKind.Resource }); // Assert Assert.Throws <ArgumentNullException>("context", () => formatter.CanRead(context: null)); }
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); }
// 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)); }
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)); }
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)); }
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))); }
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); }
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."); }
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)); }
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"); }
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()); })); }
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)); }
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); }
public void GetDefaultBaseAddress_ThrowsArgumentNull_Request() { ExceptionAssert.ThrowsArgumentNull(() => ODataInputFormatter.GetDefaultBaseAddress(null), "request"); }