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() && !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, 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).GetValue(modifiedDto));
                        }

                        result = delta;
                    }

                    return(result);
                }
                finally
                {
                    deserilizer.Error -= Error;
                }
            }
        }