Example #1
0
 private void ApplyResourceProperties(object resource, ODataResourceWrapper resourceWrapper,
                                      IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
 {
     ApplyStructuralProperties(resource, resourceWrapper, structuredType, readContext);
     ApplyNestedProperties(resource, resourceWrapper, structuredType, readContext);
 }
Example #2
0
        /// <summary>
        /// Deserializes the nested property from <paramref name="resourceInfoWrapper"/> into <paramref name="resource"/>.
        /// </summary>
        /// <param name="resource">The object into which the nested property should be read.</param>
        /// <param name="resourceInfoWrapper">The nested resource info.</param>
        /// <param name="structuredType">The type of the resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyNestedProperty(object resource, ODataNestedResourceInfoWrapper resourceInfoWrapper,
                                                IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
        {
            if (resource == null)
            {
                throw Error.ArgumentNull("resource");
            }

            if (resourceInfoWrapper == null)
            {
                throw Error.ArgumentNull("resourceInfoWrapper");
            }

            IEdmProperty edmProperty = structuredType.FindProperty(resourceInfoWrapper.NestedResourceInfo.Name);

            if (edmProperty == null)
            {
                if (!structuredType.IsOpen())
                {
                    throw new ODataException("TODO:" /*
                                                      * Error.Format(SRResources.NestedPropertyNotfound, resourceInfoWrapper.NestedResourceInfo.Name,
                                                      * structuredType.FullName())*/);
                }
            }

            foreach (ODataItemBase childItem in resourceInfoWrapper.NestedItems)
            {
                ODataEntityReferenceLinkBase entityReferenceLink = childItem as ODataEntityReferenceLinkBase;
                if (entityReferenceLink != null)
                {
                    // ignore entity reference links.
                    continue;
                }

                ODataResourceSetWrapper resourceSetWrapper = childItem as ODataResourceSetWrapper;
                if (resourceSetWrapper != null)
                {
                    if (edmProperty == null)
                    {
                        ApplyDynamicResourceSetInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name,
                                                                resource, structuredType, resourceSetWrapper, readContext);
                    }
                    else
                    {
                        ApplyResourceSetInNestedProperty(edmProperty, resource, resourceSetWrapper, readContext);
                    }

                    continue;
                }

                // It must be resource by now.
                ODataResourceWrapper resourceWrapper = (ODataResourceWrapper)childItem;
                if (resourceWrapper != null)
                {
                    if (edmProperty == null)
                    {
                        ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource,
                                                             structuredType, resourceWrapper, readContext);
                    }
                    else
                    {
                        ApplyResourceInNestedProperty(edmProperty, resource, resourceWrapper, readContext);
                    }
                }
            }
        }
        /// <summary>
        /// Deserializes the given <paramref name="deltaResourceSet"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="deltaResourceSet">The delta resource set to deserialize.</param>
        /// <param name="elementType">The element type.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <returns>The deserialized resource set object.</returns>
        public virtual IEnumerable ReadDeltaResourceSet(ODataDeltaResourceSetWrapper deltaResourceSet, IEdmStructuredTypeReference elementType, ODataDeserializerContext readContext)
        {
            if (deltaResourceSet == null)
            {
                throw Error.ArgumentNull(nameof(deltaResourceSet));
            }

            if (readContext == null)
            {
                throw Error.ArgumentNull(nameof(readContext));
            }

            // Delta Items
            foreach (ODataItemWrapper itemWrapper in deltaResourceSet.DeltaItems)
            {
                // Deleted Link
                ODataDeltaDeletedLinkWrapper deletedLinkWrapper = itemWrapper as ODataDeltaDeletedLinkWrapper;
                if (deletedLinkWrapper != null)
                {
                    yield return(ReadDeltaDeletedLink(deletedLinkWrapper, elementType, readContext));
                }

                // Added Link
                ODataDeltaLinkWrapper deltaLinkWrapper = itemWrapper as ODataDeltaLinkWrapper;
                if (deltaLinkWrapper != null)
                {
                    yield return(ReadDeltaLink(deltaLinkWrapper, elementType, readContext));
                }

                // DeletedResource
                ODataDeletedResourceWrapper deletedResourceWrapper = itemWrapper as ODataDeletedResourceWrapper;
                if (deletedResourceWrapper != null)
                {
                    // TODO: deleted resource
                    yield return(null);
                }

                // Added resource or updated resource
                ODataResourceWrapper resourceWrapper = itemWrapper as ODataResourceWrapper;
                if (resourceWrapper != null)
                {
                    IEdmModel model = readContext.Model;
                    if (model == null)
                    {
                        throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext);
                    }

                    IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType;
                    if (actualType == null)
                    {
                        throw new ODataException(Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName));
                    }

                    IEdmTypeReference        edmTypeReference = actualType.ToEdmTypeReference(true);
                    ODataEdmTypeDeserializer deserializer     = DeserializerProvider.GetEdmTypeDeserializer(edmTypeReference);
                    if (deserializer == null)
                    {
                        throw new SerializationException(
                                  Error.Format(SRResources.TypeCannotBeDeserialized, edmTypeReference.FullName()));
                    }

                    // TODO: normal resource
                    // yield return deserializer.ReadInline(resourceWrapper, edmTypeReference, readContext);
                    if (readContext.IsDeltaOfT)
                    {
                        Type          elementClrType = readContext.Model.GetClrType(elementType);
                        Type          deltaType      = typeof(Deltas.Delta <>).MakeGenericType(elementClrType);
                        Deltas.IDelta delta          = Activator.CreateInstance(deltaType) as Deltas.IDelta;
                        yield return(delta);
                    }
                    else
                    {
                        yield return(new EdmDeltaResourceObject(actualType as IEdmEntityType));
                    }

                    continue;
                }
            }
        }
Example #4
0
        /// <summary>
        /// Deserializes the given <paramref name="resourceWrapper"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="resourceWrapper">The OData resource to deserialize.</param>
        /// <param name="structuredType">The type of the resource to deserialize.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <returns>The deserialized resource.</returns>
        public virtual object ReadResource(ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType,
                                           ODataDeserializerContext readContext)
        {
            if (resourceWrapper == null)
            {
                throw Error.ArgumentNull("resourceWrapper");
            }

            if (readContext == null)
            {
                throw Error.ArgumentNull("readContext");
            }

            if (!String.IsNullOrEmpty(resourceWrapper.Resource.TypeName) && structuredType.FullName() != resourceWrapper.Resource.TypeName)
            {
                // received a derived type in a base type deserializer. delegate it to the appropriate derived type deserializer.
                IEdmModel model = readContext.Model;

                if (model == null)
                {
                    throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext);
                }

                IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType;
                if (actualType == null)
                {
                    throw new ODataException("TODO:" /*Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName)*/);
                }

                if (actualType.IsAbstract)
                {
                    //string message = Error.Format(SRResources.CannotInstantiateAbstractResourceType, resourceWrapper.Resource.TypeName);
                    throw new ODataException("TODO:");
                }

                IEdmTypeReference actualStructuredType;
                IEdmEntityType    actualEntityType = actualType as IEdmEntityType;
                if (actualEntityType != null)
                {
                    actualStructuredType = new EdmEntityTypeReference(actualEntityType, isNullable: false);
                }
                else
                {
                    actualStructuredType = new EdmComplexTypeReference(actualType as IEdmComplexType, isNullable: false);
                }

                ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(actualStructuredType);
                if (deserializer == null)
                {
                    throw new SerializationException(
                              Error.Format(SRResources.TypeCannotBeDeserialized, actualEntityType.FullName(), typeof(ODataInputFormatter).Name));
                }

                object resource = deserializer.ReadInline(resourceWrapper, actualStructuredType, readContext);

                EdmStructuredObject structuredObject = resource as EdmStructuredObject;
                if (structuredObject != null)
                {
                    structuredObject.ExpectedEdmType = structuredType.StructuredDefinition();
                }

                return(resource);
            }
            else
            {
                object resource = CreateResourceInstance(structuredType, readContext);
                ApplyResourceProperties(resource, resourceWrapper, structuredType, readContext);
                return(resource);
            }
        }
        /// <summary>
        /// Deserializes the nested property from <paramref name="resourceInfoWrapper"/> into <paramref name="resource"/>.
        /// </summary>
        /// <param name="resource">The object into which the nested property should be read.</param>
        /// <param name="resourceInfoWrapper">The nested resource info.</param>
        /// <param name="structuredType">The type of the resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyNestedProperty(object resource, ODataNestedResourceInfoWrapper resourceInfoWrapper,
                                                IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
        {
            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            if (resourceInfoWrapper == null)
            {
                throw new ArgumentNullException(nameof(resourceInfoWrapper));
            }

            IEdmProperty edmProperty = structuredType.FindProperty(resourceInfoWrapper.NestedResourceInfo.Name);

            if (edmProperty == null)
            {
                if (!structuredType.IsOpen())
                {
                    throw new ODataException(
                              Error.Format(SRResources.NestedPropertyNotfound, resourceInfoWrapper.NestedResourceInfo.Name,
                                           structuredType.FullName()));
                }
            }

            if (resourceInfoWrapper.NestedResourceSet != null)
            {
                // It's nested resource set.
                // So far, delta resource set is not supported yet.
                ODataResourceSetWrapper resourceSetWrapper = resourceInfoWrapper.NestedResourceSet as ODataResourceSetWrapper;
                if (resourceSetWrapper != null)
                {
                    if (edmProperty == null)
                    {
                        ApplyDynamicResourceSetInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name,
                                                                resource, structuredType, resourceSetWrapper, readContext);
                    }
                    else
                    {
                        ApplyResourceSetInNestedProperty(edmProperty, resource, resourceSetWrapper, readContext);
                    }
                }
            }
            else if (resourceInfoWrapper.NestedLinks == null)
            {
                // it's a nested resource, TODO, how to get rid of this logic?
                if (resourceInfoWrapper.NestedResource == null)
                {
                    if (edmProperty == null)
                    {
                        // for the dynamic, OData.net has a bug. see https://github.com/OData/odata.net/issues/977
                        ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource, structuredType, null, readContext);
                    }
                    else
                    {
                        ApplyResourceInNestedProperty(edmProperty, resource, null, readContext);
                    }
                }
                else
                {
                    // It must be resource by now. deleted resource is not supported yet.
                    ODataResourceWrapper resourceWrapper = resourceInfoWrapper.NestedResource as ODataResourceWrapper;
                    if (resourceWrapper != null)
                    {
                        if (edmProperty == null)
                        {
                            ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource,
                                                                 structuredType, resourceWrapper, readContext);
                        }
                        else
                        {
                            ApplyResourceInNestedProperty(edmProperty, resource, resourceWrapper, readContext);
                        }
                    }
                }
            }
            else
            {
                // it's a nested reference link(s), ignore entity reference links.
            }
        }