public void SetODataContentIdMapping_SetsTheContentIdMappingOnTheRequest() { // Arrange HttpRequest request = new DefaultHttpContext().Request; IDictionary <string, string> mapping = new Dictionary <string, string>(); // Act request.SetODataContentIdMapping(mapping); // Assert Assert.Equal(mapping, ODataBatchHttpRequestExtensions.GetODataContentIdMapping(request)); }
/// <summary> /// If the request has OData v3 headers in it, then process using V3 deserializer provider. /// Otherwise, process as base class. /// </summary> /// <param name="context">InputFormatter context</param> /// <param name="encoding">Encoding of request body</param> /// <returns>InputFormatterResult</returns> public override Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Type type = context.ModelType; if (type == null) { throw new ArgumentException("Model type for this request body is null", nameof(type)); } HttpRequest request = context.HttpContext.Request; if (request == null) { throw new ArgumentNullException(nameof(request)); } // Migration extension need AllowSynchronousIO to be true. (The value is false by default for .Net Core 3.0+, refer to https://github.com/dotnet/docs/issues/14835) var syncIOFeature = context.HttpContext.Features.Get <IHttpBodyControlFeature>(); if (syncIOFeature != null) { syncIOFeature.AllowSynchronousIO = true; } // 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(Task.FromResult(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> disposeList = new List <IDisposable>(); IServiceProvider fakeProvider = (new ServiceCollection()).BuildServiceProvider(); ODataDeserializerProvider deserializerProvider = new ODataMigrationDeserializerProvider(fakeProvider); object result = ReadFromStream( type, defaultValue, request.GetModel(), GetBaseAddressInternal(request), request, // Use GetODataContentIdMapping() from the namespace Microsoft.AspNet.OData.Batch. Reference: https://github.com/OData/WebApi/pull/2012 () => ODataMigrationMessageWrapper.Create(request.Body, request.Headers, ODataBatchHttpRequestExtensions.GetODataContentIdMapping(request), request.GetRequestContainer()), (objectType) => deserializerProvider.GetEdmTypeDeserializer(objectType), (objectType) => deserializerProvider.GetODataDeserializer(objectType, request), getODataDeserializerContext, (disposable) => disposeList.Add(disposable), logErrorAction); foreach (IDisposable obj in disposeList) { obj.Dispose(); } return(Task.FromResult(InputFormatterResult.Success(result))); } catch (Exception ex) { context.ModelState.AddModelError(context.ModelName, ex, context.Metadata); return(Task.FromResult(InputFormatterResult.Failure())); } }
public void GetODataContentIdMapping_NullRequest_Throws() { // Arrange & Act & Assert ExceptionAssert.ThrowsArgumentNull(() => ODataBatchHttpRequestExtensions.GetODataContentIdMapping(null), "request"); }