/// <summary> /// Invoke the middleware. /// </summary> /// <param name="context">The http context.</param> /// <returns>A task that can be awaited.</returns> public async Task Invoke(HttpContext context) { HttpRequest request = context.Request; bool isPreFlight = HttpMethods.IsOptions(request.Method); // Attempt to match the path to a batch route. ODataBatchPathMapping batchMapping = context.RequestServices.GetRequiredService <ODataBatchPathMapping>(); if (!isPreFlight && batchMapping.TryGetRouteName(context, out string routeName)) { // Get the per-route container and retrieve the batch handler. IPerRouteContainer perRouteContainer = context.RequestServices.GetRequiredService <IPerRouteContainer>(); if (perRouteContainer == null) { throw Error.InvalidOperation(SRResources.MissingODataServices, nameof(IPerRouteContainer)); } IServiceProvider rootContainer = perRouteContainer.GetODataRootContainer(routeName); ODataBatchHandler batchHandler = rootContainer.GetRequiredService <ODataBatchHandler>(); await batchHandler.ProcessBatchAsync(context, next); } else { await this.next(context); } }
internal static Uri GetODataBatchBaseUri(this HttpRequest request, string oDataRouteName, IRouter route) { Contract.Assert(request != null); if (oDataRouteName == null) { // Return request's base address. return(new Uri(request.GetDisplayUrl())); } HttpContext context = request.HttpContext; #if !NETSTANDARD2_0 // Here's workaround to help "EndpointLinkGenerator" to generator ODataBatchPathMapping batchMapping = request.HttpContext.RequestServices.GetRequiredService <ODataBatchPathMapping>(); if (batchMapping.IsEndpointRouting) { context = new DefaultHttpContext { RequestServices = request.HttpContext.RequestServices, }; IEndpointFeature endpointFeature = new ODataEndpointFeature(); endpointFeature.Endpoint = new Endpoint((d) => null, null, "anything"); context.Features.Set(endpointFeature); context.Request.Scheme = request.Scheme; context.Request.Host = request.Host; } context.Request.ODataFeature().RouteName = oDataRouteName; #endif // The IActionContextAccessor and ActionContext will be present after routing but not before // GetUrlHelper only uses the HttpContext and the Router, which we have so construct a dummy // action context. ActionContext actionContext = new ActionContext { HttpContext = context, RouteData = new RouteData(), ActionDescriptor = new ActionDescriptor() }; actionContext.RouteData.Routers.Add(route); IUrlHelperFactory factory = request.HttpContext.RequestServices.GetRequiredService <IUrlHelperFactory>(); IUrlHelper helper = factory.GetUrlHelper(actionContext); RouteValueDictionary routeData = new RouteValueDictionary() { { ODataRouteConstants.ODataPath, String.Empty } }; RouteValueDictionary batchRouteData = request.ODataFeature().BatchRouteData; if (batchRouteData != null && batchRouteData.Any()) { foreach (var data in batchRouteData) { routeData.Add(data.Key, data.Value); } } string baseAddress = helper.Link(oDataRouteName, routeData); if (baseAddress == null) { throw new InvalidOperationException(SRResources.UnableToDetermineBaseUrl); } return(new Uri(baseAddress)); }