Example #1
0
        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);
        }
Example #2
0
        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;
                }
            }
        }
Example #4
0
        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);
        }
Example #5
0
        /// <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;
            }));
        }
Example #6
0
        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));
        }
Example #7
0
        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;
                }
            }
        }
Example #11
0
        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);
 }
Example #14
0
        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);
        }
Example #15
0
        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));
        }
Example #16
0
        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);
            }
        }
Example #17
0
        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;
                    }
                }
            }
        }
Example #19
0
        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);
        }