private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) { object result; HttpContentHeaders contentHeaders = content == null ? null : content.Headers; // If content length is 0 then return default value for this type if (contentHeaders == null || contentHeaders.ContentLength == 0) { result = GetDefaultValueForType(type); } else { IEdmModel model = Request.ODataProperties().Model; if (model == null) { throw Error.InvalidOperation(SRResources.RequestMustHaveModel); } IEdmTypeReference expectedPayloadType; ODataDeserializer deserializer = GetDeserializer(type, Request.ODataProperties().Path, model, _deserializerProvider, out expectedPayloadType); if (deserializer == null) { throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName); } try { ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings(MessageReaderSettings); oDataReaderSettings.BaseUri = GetBaseAddress(Request); IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders, Request.GetODataContentIdMapping()); ODataMessageReader oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model); Request.RegisterForDispose(oDataMessageReader); ODataPath path = Request.ODataProperties().Path; ODataDeserializerContext readContext = new ODataDeserializerContext { Path = path, Model = model, Request = Request, ResourceType = type, ResourceEdmType = expectedPayloadType, RequestContext = Request.GetRequestContext(), }; result = deserializer.Read(oDataMessageReader, type, readContext); } catch (Exception e) { if (formatterLogger == null) { throw; } formatterLogger.LogError(String.Empty, e); result = GetDefaultValueForType(type); } } return(result); }
private static IEnumerable CovertResourceSetIds(IEnumerable sources, ODataResourceSetWrapper resourceSet, IEdmCollectionTypeReference collectionType, ODataDeserializerContext readContext) { IEdmEntityTypeReference entityTypeReference = collectionType.ElementType().AsEntity(); int i = 0; foreach (object item in sources) { object newItem = CovertResourceId(item, resourceSet.Resources[i].Resource, entityTypeReference, readContext); i++; yield return(newItem); } }
public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (readContext == null) { throw new ArgumentNullException(nameof(readContext)); } HttpActionDescriptor actionDescriptor = readContext.Request.GetActionDescriptor(); if (actionDescriptor != null && !actionDescriptor.GetCustomAttributes <ActionAttribute>().Any() && !actionDescriptor.GetCustomAttributes <CreateAttribute>().Any() && !actionDescriptor.GetCustomAttributes <UpdateAttribute>().Any() && !actionDescriptor.GetCustomAttributes <PartialUpdateAttribute>().Any()) { throw new InvalidOperationException($"{nameof(DefaultODataActionCreateUpdateParameterDeserializer)} is designed for odata actions|creates|updates|partialUpdates only"); } TypeInfo typeInfo = type.GetTypeInfo(); IDependencyResolver dependencyResolver = readContext.Request.GetOwinContext() .GetDependencyResolver(); ITimeZoneManager timeZoneManager = dependencyResolver.Resolve <ITimeZoneManager>(); JToken requestJsonBody = (JToken)readContext.Request.Properties["ContentStreamAsJson"]; using (JsonReader requestJsonReader = requestJsonBody.CreateReader()) { void Error(object?sender, Newtonsoft.Json.Serialization.ErrorEventArgs e) { if (e.ErrorContext.Error is JsonSerializationException && e.ErrorContext.Error.Message.StartsWith("Could not find member ", StringComparison.InvariantCultureIgnoreCase)) { if (e.CurrentObject is IOpenType openDto) { openDto.Properties = openDto.Properties ?? new Dictionary <string, object?>(); if (requestJsonReader.Read()) { openDto.Properties.Add((string)(e.ErrorContext.Member ?? "UnknownMember"), requestJsonReader.Value); } } e.ErrorContext.Handled = true; } if (e.ErrorContext.Handled == false) { readContext.Request.Properties["Request_Body_Json_Parse_Error"] = e.ErrorContext.Error; // This code is being executed in a try/catch which is located in ODataMediaTypeFormatter. That class will return defaul value (null) to actions which results into NRE in most cases. } } JsonSerializerSettings settings = DefaultJsonContentFormatter.DeserializeSettings(); settings.Converters = new JsonConverter[] { _odataJsonDeserializerEnumConverter, _stringCorrectorsConverters, new ODataJsonDeSerializerDateTimeOffsetTimeZone(timeZoneManager) }; settings.MissingMemberHandling = MissingMemberHandling.Error; JsonSerializer deserilizer = JsonSerializer.Create(settings); deserilizer.Error += Error; try { object?result = null; if (!typeof(Delta).GetTypeInfo().IsAssignableFrom(typeInfo)) { result = deserilizer.Deserialize(requestJsonReader, typeInfo) !; } else { List <string> changedPropNames = new List <string>(); using (JsonReader jsonReaderForGettingSchema = requestJsonBody.CreateReader()) { while (jsonReaderForGettingSchema.Read()) { if (jsonReaderForGettingSchema.Value != null && jsonReaderForGettingSchema.TokenType == JsonToken.PropertyName) { changedPropNames.Add(jsonReaderForGettingSchema.Value.ToString() !); } } } TypeInfo dtoType = typeInfo.GetGenericArguments().ExtendedSingle("Finding dto type from delta").GetTypeInfo(); object?modifiedDto = deserilizer.Deserialize(requestJsonReader, dtoType); Delta delta = (Delta)(Activator.CreateInstance(typeInfo) !); if (modifiedDto is IOpenType openTypeDto && openTypeDto.Properties?.Any() == true) { delta.TrySetPropertyValue(nameof(IOpenType.Properties), openTypeDto); } foreach (string changedProp in changedPropNames.Where(p => p != nameof(IOpenType.Properties) && dtoType.GetProperty(p) != null)) { delta.TrySetPropertyValue(changedProp, (dtoType.GetProperty(changedProp) ?? throw new InvalidOperationException($"{changedProp} could not be found in {dtoType.FullName}")).GetValue(modifiedDto)); } result = delta; } return(result); } finally { deserilizer.Error -= Error; } } }
public override object ReadResource(ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext) { object resource = base.ReadResource(resourceWrapper, structuredType, readContext); if (resourceWrapper.Resource.ETag != null) { Guid label = DecodeETag(resourceWrapper.Resource.ETag); if (resource is Customer c) { c.Label = label; } else if (resource is IDelta delta) { Type deltaType = typeof(Delta <>).MakeGenericType(typeof(Customer)); var fieldInfo = deltaType.GetField("_updatableProperties", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); var updateProperties = fieldInfo.GetValue(delta) as HashSet <string>; updateProperties.Add("Label"); delta.TrySetPropertyValue("Label", label); } } return(resource); }
/// <inheritdoc/> public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) { if (type == null) { throw Error.ArgumentNull("type"); } if (readStream == null) { throw Error.ArgumentNull("readStream"); } return(TaskHelpers.RunSynchronously <object>(() => { object result; HttpContentHeaders contentHeaders = content == null ? null : content.Headers; // If content length is 0 then return default value for this type if (contentHeaders != null && contentHeaders.ContentLength == 0) { result = GetDefaultValueForType(type); } else { bool isPatchMode = TryGetInnerTypeForDelta(ref type); ODataDeserializer deserializer = ODataDeserializerProvider.GetODataDeserializer(type); if (deserializer == null) { throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName); } ODataMessageReader oDataMessageReader = null; ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = true }; try { IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders); oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, ODataDeserializerProvider.EdmModel); ODataDeserializerContext readContext = new ODataDeserializerContext { IsPatchMode = isPatchMode, PatchKeyMode = PatchKeyMode, Request = Request, Model = Model }; result = deserializer.Read(oDataMessageReader, readContext); } catch (Exception e) { if (formatterLogger == null) { throw; } formatterLogger.LogError(String.Empty, e); result = GetDefaultValueForType(type); } finally { if (oDataMessageReader != null) { oDataMessageReader.Dispose(); } } } return result; })); }
private static object ConvertCollectionValue(ODataCollectionValue collection, IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext) { IEdmCollectionTypeReference collectionTypeReference = propertyType as IEdmCollectionTypeReference; return(deserializerProvider.GetEdmTypeDeserializer((IEdmTypeReference)collectionTypeReference).ReadInline((object)collection, (IEdmTypeReference)collectionTypeReference, readContext)); }
internal static object ConvertValue(object oDataValue, ref IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext, out EdmTypeKind typeKind) { if (oDataValue == null) { typeKind = EdmTypeKind.None; return((object)null); } ODataComplexValue complexValue = oDataValue as ODataComplexValue; if (complexValue != null) { typeKind = EdmTypeKind.Complex; return(DeserializationHelpers.ConvertComplexValue(complexValue, ref propertyType, deserializerProvider, readContext)); } ODataCollectionValue collection = oDataValue as ODataCollectionValue; if (collection != null) { typeKind = EdmTypeKind.Collection; return(DeserializationHelpers.ConvertCollectionValue(collection, propertyType, deserializerProvider, readContext)); } typeKind = EdmTypeKind.Primitive; return(oDataValue); }
public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) { if (type == null) { throw Error.ArgumentNull("type"); } if (readStream == null) { throw Error.ArgumentNull("readStream"); } if (_request == null) { throw Error.InvalidOperation(SRResources.ReadFromStreamAsyncMustHaveRequest); } return(TaskHelpers.RunSynchronously <object>(() => { object result; HttpContentHeaders contentHeaders = content == null ? null : content.Headers; // If content length is 0 then return default value for this type if (contentHeaders == null || contentHeaders.ContentLength == 0) { result = GetDefaultValueForType(type); } else { IEdmModel model = _request.GetEdmModel(); if (model == null) { throw Error.InvalidOperation(SRResources.RequestMustHaveModel); } Type originalType = type; bool isPatchMode = TryGetInnerTypeForDelta(ref type); ODataDeserializer deserializer = _deserializerProvider.GetODataDeserializer(model, type); if (deserializer == null) { throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName); } ODataMessageReader oDataMessageReader = null; ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = true, MessageQuotas = MessageReaderQuotas, BaseUri = GetBaseAddress(_request) }; try { IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders); oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model); _request.RegisterForDispose(oDataMessageReader); ODataPath path = _request.GetODataPath(); ODataDeserializerContext readContext = new ODataDeserializerContext { IsPatchMode = isPatchMode, Path = path, Model = model, Request = _request }; if (isPatchMode) { readContext.PatchEntityType = originalType; } result = deserializer.Read(oDataMessageReader, readContext); } catch (Exception e) { if (formatterLogger == null) { throw; } formatterLogger.LogError(String.Empty, e); result = GetDefaultValueForType(type); } } return result; })); }
public override IEnumerable ReadFeed(ODataFeedWithEntries feed, IEdmEntityTypeReference elementType, ODataDeserializerContext readContext) { IEnumerable feedInstance = base.ReadFeed(feed, elementType, readContext); return(feedInstance); }
public override void ApplyStructuralProperty(object resource, ODataProperty structuralProperty, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext) { if (structuralProperty?.Value != null) { if (structuralProperty.Value is DateTimeOffset) { IDependencyResolver dependencyResolver = readContext.Request.GetOwinContext() .GetDependencyResolver(); ITimeZoneManager timeZoneManager = dependencyResolver.Resolve <ITimeZoneManager>(); structuralProperty.Value = timeZoneManager.MapFromClientToServer(((DateTimeOffset)structuralProperty.Value)); } else if (structuralProperty.Value is string) { string rawString = structuralProperty.Value.ToString(); foreach (IStringCorrector stringCorrector in _stringCorrectors) { rawString = stringCorrector.CorrectString(rawString); } structuralProperty.Value = rawString; } } try { base.ApplyStructuralProperty(resource, structuralProperty, structuredType, readContext); } catch (ODataException ex) { if (ex.Message != "Does not support untyped value in non-open type.") { throw; } } }
internal static object ReadFromStream( #endif Type type, object defaultValue, IEdmModel model, ODataVersion version, Uri baseAddress, IWebApiRequestMessage internalRequest, Func <IODataRequestMessage> getODataRequestMessage, Func <IEdmTypeReference, ODataDeserializer> getEdmTypeDeserializer, Func <Type, ODataDeserializer> getODataPayloadDeserializer, Func <ODataDeserializerContext> getODataDeserializerContext, Action <IDisposable> registerForDisposeAction, Action <Exception> logErrorAction) { object result; IEdmTypeReference expectedPayloadType; ODataDeserializer deserializer = GetDeserializer(type, internalRequest.Context.Path, model, getEdmTypeDeserializer, getODataPayloadDeserializer, out expectedPayloadType); if (deserializer == null) { throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, typeof(ODataInputFormatterHelper).FullName); } try { ODataMessageReaderSettings oDataReaderSettings = internalRequest.ReaderSettings; oDataReaderSettings.BaseUri = baseAddress; oDataReaderSettings.Validations = oDataReaderSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType; oDataReaderSettings.Version = version; IODataRequestMessage oDataRequestMessage = getODataRequestMessage(); string preferHeader = RequestPreferenceHelpers.GetRequestPreferHeader(internalRequest.Headers); string annotationFilter = null; if (!String.IsNullOrEmpty(preferHeader)) { oDataRequestMessage.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader); annotationFilter = oDataRequestMessage.PreferHeader().AnnotationFilter; } if (annotationFilter != null) { oDataReaderSettings.ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter(annotationFilter); } ODataMessageReader oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model); registerForDisposeAction(oDataMessageReader); ODataPath path = internalRequest.Context.Path; ODataDeserializerContext readContext = getODataDeserializerContext(); readContext.Path = path; readContext.Model = model; readContext.ResourceType = type; readContext.ResourceEdmType = expectedPayloadType; #if NETCORE result = await deserializer.ReadAsync(oDataMessageReader, type, readContext); #else result = deserializer.Read(oDataMessageReader, type, readContext); #endif } catch (Exception e) { logErrorAction(e); result = defaultValue; } return(result); }
private static object CovertResourceId(object source, ODataResource resource, IEdmEntityTypeReference entityTypeReference, ODataDeserializerContext readContext) { Contract.Assert(resource != null); Contract.Assert(source != null); if (resource.Id == null || resource.Properties.Any()) { return(source); } HttpRequest request = readContext.Request; string serviceRoot = request.CreateODataLink(); IEnumerable <KeyValuePair <string, object> > keyValues = GetKeys(request, serviceRoot, resource.Id, request.GetSubServiceProvider()); IList <IEdmStructuralProperty> keys = entityTypeReference.Key().ToList(); if (keys.Count == 1 && keyValues.Count() == 1) { // TODO: make sure the enum key works object propertyValue = keyValues.First().Value; DeserializationHelpers.SetDeclaredProperty(source, EdmTypeKind.Primitive, keys[0].Name, propertyValue, keys[0], readContext); return(source); } IDictionary <string, object> keyValuesDic = keyValues.ToDictionary(e => e.Key, e => e.Value); foreach (IEdmStructuralProperty key in keys) { object value; if (keyValuesDic.TryGetValue(key.Name, out value)) { // TODO: make sure the enum key works DeserializationHelpers.SetDeclaredProperty(source, EdmTypeKind.Primitive, key.Name, value, key, readContext); } } return(source); }
public override void ApplyStructuralProperty(object resource, ODataProperty structuralProperty, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext) { if (structuralProperty != null && structuralProperty.Value is ODataUntypedValue) { // Below is a Q&D mapper I am using in my test to represent properties var tupl = WebApplication1.Models.RuntimeClassesHelper.GetFieldsAndTypes().Where(t => t.Item1 == structuralProperty.Name).FirstOrDefault(); if (tupl != null) { ODataUntypedValue untypedValue = structuralProperty.Value as ODataUntypedValue; if (untypedValue != null) { try { object jsonVal = JsonConvert.DeserializeObject(untypedValue.RawValue); Func<object, object> typeConverterFunc; if (jsonVal != null && simpleTypeConverters.TryGetValue(jsonVal.GetType(), out typeConverterFunc)) { jsonVal = typeConverterFunc(jsonVal); } structuralProperty.Value = jsonVal; } catch(Exception e) { /* Todo: handle exceptions ? */ } } } } base.ApplyStructuralProperty(resource, structuralProperty, structuredType, readContext); }
private static object CovertResourceId(object source, ODataResource resource, IEdmEntityTypeReference entityTypeReference, ODataDeserializerContext readContext) { Contract.Assert(resource != null); Contract.Assert(source != null); if (resource.Id == null || resource.Properties.Any()) { return(source); } HttpRequest request = readContext.Request; // IWebApiUrlHelper urlHelper = readContext.InternalUrlHelper; // DefaultODataPathHandler pathHandler = new DefaultODataPathHandler(); //string serviceRoot = urlHelper.CreateODataLink( // request.Context.RouteName, // request.PathHandler, // new List<ODataPathSegment>()); string serviceRoot = null; // TODOO IEnumerable <KeyValuePair <string, object> > keyValues = GetKeys(request, serviceRoot, resource.Id /*, request.RequestContainer*/); IList <IEdmStructuralProperty> keys = entityTypeReference.Key().ToList(); if (keys.Count == 1 && keyValues.Count() == 1) { // TODO: make sure the enum key works object propertyValue = keyValues.First().Value; DeserializationHelpers.SetDeclaredProperty(source, EdmTypeKind.Primitive, keys[0].Name, propertyValue, keys[0], readContext); return(source); } IDictionary <string, object> keyValuesDic = keyValues.ToDictionary(e => e.Key, e => e.Value); foreach (IEdmStructuralProperty key in keys) { object value; if (keyValuesDic.TryGetValue(key.Name, out value)) { // TODO: make sure the enum key works DeserializationHelpers.SetDeclaredProperty(source, EdmTypeKind.Primitive, key.Name, value, key, readContext); } } return(source); }
private static object ConvertComplexValue(ODataComplexValue complexValue, ref IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext) { IEdmComplexTypeReference complexTypeReference = propertyType != null?propertyType.AsComplex() : (IEdmComplexTypeReference) new EdmComplexTypeReference((IEdmType)readContext.Model.FindType(complexValue.TypeName) as IEdmComplexType, true); return(deserializerProvider.GetEdmTypeDeserializer((IEdmTypeReference)complexTypeReference).ReadInline((object)complexValue, propertyType, readContext)); }
public void ReadDeltaResource_Returns_DeletedResource(bool typed) { // Arrange IEdmModel model = GetEdmModel(); IEdmEntityType customer = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Customer"); IEdmStructuredTypeReference elementType = new EdmEntityTypeReference(customer, true); Mock <ODataDeserializerProvider> deserializerProvider = new Mock <ODataDeserializerProvider>(); ODataResourceDeserializer resourceDeserializer = new ODataResourceDeserializer(deserializerProvider.Object); Uri id = new Uri("Customers(8)", UriKind.RelativeOrAbsolute); ODataDeletedResource customerDeleted = new ODataDeletedResource(id, DeltaDeletedEntryReason.Deleted) { Properties = new List <ODataProperty> { new ODataProperty { Name = "FirstName", Value = "Peter" }, new ODataProperty { Name = "LastName", Value = "John" } } }; ODataResourceWrapper resourceWrapper = new ODataResourceWrapper(customerDeleted); ODataDeserializerContext context = new ODataDeserializerContext { Model = model, }; if (typed) { context.ResourceType = typeof(DeltaSet <>); } else { context.ResourceType = typeof(EdmChangedObjectCollection); } deserializerProvider.Setup(d => d.GetEdmTypeDeserializer(It.IsAny <IEdmTypeReference>(), false)).Returns(resourceDeserializer); ODataDeltaResourceSetDeserializer deserializer = new ODataDeltaResourceSetDeserializer(deserializerProvider.Object); // Act object result = deserializer.ReadDeltaResource(resourceWrapper, elementType, context); // Assert Action <Delta> testPropertyAction = d => { d.TryGetPropertyValue("FirstName", out object firstName); Assert.Equal("Peter", firstName); d.TryGetPropertyValue("LastName", out object lastName); Assert.Equal("John", lastName); }; if (typed) { DeltaDeletedResource <Customer> deltaDeletedResource = Assert.IsType <DeltaDeletedResource <Customer> >(result); Assert.Equal(id, deltaDeletedResource.Id); Assert.Equal(DeltaDeletedEntryReason.Deleted, deltaDeletedResource.Reason); testPropertyAction(deltaDeletedResource); } else { EdmDeltaDeletedResourceObject deltaDeletedResource = Assert.IsType <EdmDeltaDeletedResourceObject>(result); Assert.Equal(id, deltaDeletedResource.Id); Assert.Equal(DeltaDeletedEntryReason.Deleted, deltaDeletedResource.Reason); testPropertyAction(deltaDeletedResource); } }
internal static void ApplyProperty(ODataProperty property, IEdmStructuredTypeReference resourceType, object resource, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext) { IEdmProperty property1 = resourceType.FindProperty(property.Name); string name = property.Name; IEdmTypeReference type = property1?.Type; EdmTypeKind typeKind; object obj = DeserializationHelpers.ConvertValue(property.Value, ref type, deserializerProvider, readContext, out typeKind); switch (typeKind) { case EdmTypeKind.Primitive: if (!readContext.IsUntyped) { obj = EdmPrimitiveHelpers.ConvertPrimitiveValue(obj, DeserializationHelpers.GetPropertyType(resource, name)); break; } break; case EdmTypeKind.Collection: DeserializationHelpers.SetCollectionProperty(resource, property1, obj); return; } DeserializationHelpers.SetProperty(resource, name, obj); }
public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { HttpActionDescriptor actionDescriptor = readContext.Request.GetActionDescriptor(); if (actionDescriptor != null && !actionDescriptor.GetCustomAttributes <ActionAttribute>().Any() && !actionDescriptor.GetCustomAttributes <CreateAttribute>().Any() && !actionDescriptor.GetCustomAttributes <UpdateAttribute>().Any()) { throw new InvalidOperationException($"{nameof(DefaultODataActionCreateUpdateParameterDeserializer)} is designed for odata actions|creates|updates only"); } TypeInfo typeInfo = type.GetTypeInfo(); IDependencyResolver dependencyResolver = readContext.Request.GetOwinContext() .GetDependencyResolver(); ITimeZoneManager timeZoneManager = dependencyResolver.Resolve <ITimeZoneManager>(); using (StreamReader requestStreamReader = new StreamReader(readContext.Request.Content.ReadAsStreamAsync().GetAwaiter().GetResult())) { using (JsonTextReader requestJsonReader = new JsonTextReader(requestStreamReader)) { void error(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs e) { if (e.ErrorContext.Error is JsonSerializationException && e.ErrorContext.Error.Message.StartsWith("Could not find member ")) { if (e.CurrentObject is IOpenDto) { IOpenDto openDto = (IOpenDto)e.CurrentObject; openDto.Properties = openDto.Properties ?? new Dictionary <string, object>(); if (requestJsonReader.Read()) { openDto.Properties.Add((string)e.ErrorContext.Member, requestJsonReader.Value); } } e.ErrorContext.Handled = true; } } JsonSerializer deserilizer = JsonSerializer.Create(new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, DateFormatHandling = DateFormatHandling.IsoDateFormat, Converters = new JsonConverter[] { _odataJsonDeserializerEnumConverter, _stringFormatterConvert, new ODataJsonDeSerializerDateTimeOffsetTimeZone(timeZoneManager) }, MissingMemberHandling = MissingMemberHandling.Error }); deserilizer.Error += error; try { object result = deserilizer.Deserialize(requestJsonReader, typeInfo); return(result); } finally { deserilizer.Error -= error; } } } }
public override object CreateEntityResource(IEdmEntityTypeReference entityType, ODataDeserializerContext readContext) { var resource = base.CreateEntityResource(entityType, readContext); var edmEntityObject = resource as EdmEntityObject; if (edmEntityObject != null) { // we force web api to use our own EdmEntityObject which implements IODataEntityObject resource = new ServiceApiEdmEntityObject(entityType); } return(resource); }