|
12 | 12 | using Microsoft.AspNet.OData.Extensions; |
13 | 13 | using Microsoft.AspNet.OData.Test.Abstraction; |
14 | 14 | using Microsoft.AspNet.OData.Test.Common; |
| 15 | +using Microsoft.Extensions.DependencyInjection; |
| 16 | +using Microsoft.Extensions.DependencyInjection.Extensions; |
15 | 17 | using Xunit; |
16 | 18 | #if !NETCORE |
17 | 19 | using System.Web.Http; |
18 | 20 | using System.Web.Http.Routing; |
19 | 21 | #else |
| 22 | +using Microsoft.AspNetCore.Http; |
20 | 23 | using Microsoft.AspNetCore.Mvc; |
21 | 24 | using Newtonsoft.Json; |
22 | 25 | #endif |
@@ -727,7 +730,7 @@ public async Task SendAsync_CorrectlyHandlesCookieHeader() |
727 | 730 | var changesetRef = $"changeset_{Guid.NewGuid()}"; |
728 | 731 | var endpoint = "http://localhost"; |
729 | 732 |
|
730 | | - Type[] controllers = new[] { typeof(BatchTestCustomersController), typeof(BatchTestOrdersController), }; |
| 733 | + Type[] controllers = new[] { typeof(BatchTestOrdersController), }; |
731 | 734 | var server = TestServerFactory.Create(controllers, (config) => |
732 | 735 | { |
733 | 736 | var builder = ODataConventionModelBuilderFactory.Create(config); |
@@ -782,8 +785,73 @@ public async Task SendAsync_CorrectlyHandlesCookieHeader() |
782 | 785 | var response = await client.SendAsync(batchRequest); |
783 | 786 |
|
784 | 787 | ExceptionAssert.DoesNotThrow(() => response.EnsureSuccessStatusCode()); |
| 788 | + } |
| 789 | + |
| 790 | + [Fact] |
| 791 | + public async Task ProcessBatchAsync_PreservesHttpContext() |
| 792 | + { |
| 793 | + var batchRef = $"batch_{Guid.NewGuid()}"; |
| 794 | + var changesetRef = $"changeset_{Guid.NewGuid()}"; |
| 795 | + var endpoint = "http://localhost"; |
| 796 | + |
| 797 | + Type[] controllers = new[] { typeof(BatchTestOrdersController), }; |
| 798 | + var server = TestServerFactory.Create( |
| 799 | + controllers, |
| 800 | + config => |
| 801 | + { |
| 802 | + var builder = ODataConventionModelBuilderFactory.Create(config); |
| 803 | + builder.EntitySet<BatchTestOrder>("BatchTestOrders"); |
| 804 | + |
| 805 | + config.MapODataServiceRoute("odata", null, builder.GetEdmModel(), new CustomODataBatchHandler()); |
| 806 | + config.Expand(); |
| 807 | + config.EnableDependencyInjection(); |
| 808 | + }, |
| 809 | + config => |
| 810 | + { |
| 811 | + config.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>(); |
| 812 | + }); |
| 813 | + |
| 814 | + var client = TestServerFactory.CreateClient(server); |
| 815 | + |
| 816 | + var orderId = 2; |
| 817 | + var createOrderPayload = $@"{{""@odata.type"":""Microsoft.AspNet.OData.Test.Batch.BatchTestOrder"",""Id"":{orderId},""Amount"":50}}"; |
| 818 | + |
| 819 | + var batchRequest = new HttpRequestMessage(HttpMethod.Post, $"{endpoint}/$batch"); |
| 820 | + batchRequest.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("text/plain")); |
| 821 | + |
| 822 | + var batchContent = $@" |
| 823 | +--{batchRef} |
| 824 | +Content-Type: multipart/mixed;boundary={changesetRef} |
| 825 | +
|
| 826 | +--{changesetRef} |
| 827 | +Content-Type: application/http |
| 828 | +Content-Transfer-Encoding: binary |
| 829 | +Content-ID: 1 |
| 830 | +
|
| 831 | +POST {endpoint}/BatchTestOrders HTTP/1.1 |
| 832 | +Content-Type: application/json;type=entry |
| 833 | +Prefer: return=representation |
785 | 834 |
|
786 | | - // TODO: assert somehow? |
| 835 | +{createOrderPayload} |
| 836 | +--{changesetRef}-- |
| 837 | +--{batchRef} |
| 838 | +Content-Type: application/http |
| 839 | +Content-Transfer-Encoding: binary |
| 840 | +
|
| 841 | +GET {endpoint}/BatchTestOrders({orderId}) HTTP/1.1 |
| 842 | +Content-Type: application/json;type=entry |
| 843 | +Prefer: return=representation |
| 844 | +
|
| 845 | +--{batchRef}-- |
| 846 | +"; |
| 847 | + |
| 848 | + var httpContent = new StringContent(batchContent); |
| 849 | + httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse($"multipart/mixed;boundary={batchRef}"); |
| 850 | + httpContent.Headers.ContentLength = batchContent.Length; |
| 851 | + batchRequest.Content = httpContent; |
| 852 | + var response = await client.SendAsync(batchRequest); |
| 853 | + |
| 854 | + ExceptionAssert.DoesNotThrow(() => response.EnsureSuccessStatusCode()); |
787 | 855 | } |
788 | 856 | #endif |
789 | 857 | } |
@@ -824,6 +892,13 @@ public class BatchTestOrder |
824 | 892 | return new List<BatchTestOrder> { order01 }; |
825 | 893 | }); |
826 | 894 |
|
| 895 | + |
| 896 | + [EnableQuery] |
| 897 | + public SingleResult<BatchTestOrder> Get([FromODataUri]int key) |
| 898 | + { |
| 899 | + return SingleResult.Create(Orders.Where(d => d.Id.Equals(key)).AsQueryable()); |
| 900 | + } |
| 901 | + |
827 | 902 | public static IList<BatchTestOrder> Orders |
828 | 903 | { |
829 | 904 | get |
@@ -927,5 +1002,22 @@ public class BatchTestHeadersCustomer |
927 | 1002 | { |
928 | 1003 | public int Id { get; set; } |
929 | 1004 | } |
| 1005 | + |
| 1006 | + public class CustomODataBatchHandler : DefaultODataBatchHandler |
| 1007 | + { |
| 1008 | + /// <inheritdoc /> |
| 1009 | + public override async Task ProcessBatchAsync(HttpContext context, RequestDelegate nextHandler) |
| 1010 | + { |
| 1011 | + // Retrieve current httpcontext. |
| 1012 | + var httpContextAccessor = context.RequestServices.GetService<IHttpContextAccessor>(); |
| 1013 | + var beforeContext = httpContextAccessor?.HttpContext; |
| 1014 | + await base.ProcessBatchAsync(context, nextHandler); |
| 1015 | + var afterContext = httpContextAccessor?.HttpContext; |
| 1016 | + if (httpContextAccessor != null) |
| 1017 | + { |
| 1018 | + Assert.Equal(beforeContext, afterContext); |
| 1019 | + } |
| 1020 | + } |
| 1021 | + } |
930 | 1022 | #endif |
931 | 1023 | } |
0 commit comments