Esempio n. 1
0
            internal static object ConvertFeed(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference, ODataDeserializerContext readContext)
            {
                IEdmCollectionTypeReference collectionType = edmTypeReference.AsCollection();

                EdmEntitySet tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp",
                                                              collectionType.ElementType().AsEntity().EntityDefinition());

                ODataReader odataReader = oDataMessageReader.CreateODataFeedReader(tempEntitySet,
                                                                                   collectionType.ElementType().AsEntity().EntityDefinition());
                ODataFeedWithEntries feed =
                    ODataEntityDeserializer.ReadEntryOrFeed(odataReader) as ODataFeedWithEntries;

                ODataFeedDeserializer feedDeserializer =
                    (ODataFeedDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType);

                object      result     = feedDeserializer.ReadInline(feed, collectionType, readContext);
                IEnumerable enumerable = result as IEnumerable;

                if (enumerable != null)
                {
                    IEnumerable newEnumerable = CovertFeedIds(enumerable, feed, collectionType, readContext);
                    if (readContext.IsUntyped)
                    {
                        EdmEntityObjectCollection entityCollection =
                            new EdmEntityObjectCollection(collectionType);
                        foreach (EdmEntityObject entity in newEnumerable)
                        {
                            entityCollection.Add(entity);
                        }

                        return(entityCollection);
                    }
                    else
                    {
                        IEdmTypeReference elementTypeReference = collectionType.ElementType();

                        Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference,
                                                                       readContext.Model);
                        IEnumerable castedResult =
                            CastMethodInfo.MakeGenericMethod(elementClrType)
                            .Invoke(null, new object[] { newEnumerable }) as IEnumerable;
                        return(castedResult);
                    }
                }

                return(null);
            }
        public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

            IEdmAction action = GetAction(readContext);

            Contract.Assert(action != null);

            // Create the correct resource type;
            Dictionary <string, object> payload;

            if (type == typeof(ODataActionParameters))
            {
                payload = new ODataActionParameters();
            }
            else
            {
                payload = new ODataUntypedActionParameters(action);
            }

            ODataParameterReader reader = messageReader.CreateODataParameterReader(action);

            while (reader.Read())
            {
                string parameterName             = null;
                IEdmOperationParameter parameter = null;

                switch (reader.State)
                {
                case ODataParameterReaderState.Value:
                    parameterName = reader.Name;
                    parameter     = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
                    // ODataLib protects against this but asserting just in case.
                    Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName));
                    if (parameter.Type.IsPrimitive())
                    {
                        payload[parameterName] = reader.Value;
                    }
                    else
                    {
                        ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(parameter.Type);
                        payload[parameterName] = deserializer.ReadInline(reader.Value, parameter.Type, readContext);
                    }
                    break;

                case ODataParameterReaderState.Collection:
                    parameterName = reader.Name;
                    parameter     = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
                    // ODataLib protects against this but asserting just in case.
                    Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName));
                    IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference;
                    Contract.Assert(collectionType != null);
                    ODataCollectionValue        value = ReadCollection(reader.CreateCollectionReader());
                    ODataCollectionDeserializer collectionDeserializer = (ODataCollectionDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType);
                    payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext);
                    break;

                case ODataParameterReaderState.Entry:
                    parameterName = reader.Name;
                    parameter     = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
                    Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName));

                    IEdmEntityTypeReference entityTypeReference = parameter.Type as IEdmEntityTypeReference;
                    Contract.Assert(entityTypeReference != null);

                    ODataReader entryReader = reader.CreateEntryReader();
                    object      item        = ODataEntityDeserializer.ReadEntryOrFeed(entryReader);
                    var         savedProps  = new List <ODataProperty>();
                    if (item is ODataEntryWithNavigationLinks)
                    {
                        var obj = CreateDataObject(readContext.Model as DataObjectEdmModel, entityTypeReference, item as ODataEntryWithNavigationLinks, out Type objType);
                        payload[parameterName] = obj;
                        break;
                    }

                    ODataEntityDeserializer entityDeserializer = (ODataEntityDeserializer)DeserializerProvider.GetEdmTypeDeserializer(entityTypeReference);
                    payload[parameterName] = entityDeserializer.ReadInline(item, entityTypeReference, readContext);
                    break;

                case ODataParameterReaderState.Feed:
                    parameterName = reader.Name;
                    parameter     = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
                    Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName));

                    IEdmCollectionTypeReference feedType = parameter.Type as IEdmCollectionTypeReference;
                    Contract.Assert(feedType != null);

                    ODataReader          feedReader = reader.CreateFeedReader();
                    object               feed       = ODataEntityDeserializer.ReadEntryOrFeed(feedReader);
                    IEnumerable          enumerable;
                    ODataFeedWithEntries odataFeedWithEntries = feed as ODataFeedWithEntries;
                    if (odataFeedWithEntries != null)
                    {
                        List <DataObject> list = new List <DataObject>();
                        Type objType           = null;
                        foreach (ODataEntryWithNavigationLinks entry in odataFeedWithEntries.Entries)
                        {
                            list.Add(CreateDataObject(readContext.Model as DataObjectEdmModel, feedType.ElementType() as IEdmEntityTypeReference, entry, out objType));
                        }

                        IEnumerable castedResult =
                            _castMethodInfo.MakeGenericMethod(objType)
                            .Invoke(null, new[] { list }) as IEnumerable;
                        payload[parameterName] = castedResult;
                        break;
                    }

                    ODataFeedDeserializer feedDeserializer = (ODataFeedDeserializer)DeserializerProvider.GetEdmTypeDeserializer(feedType);

                    object result = feedDeserializer.ReadInline(feed, feedType, readContext);

                    IEdmTypeReference elementTypeReference = feedType.ElementType();
                    Contract.Assert(elementTypeReference.IsEntity());

                    enumerable = result as IEnumerable;
                    if (enumerable != null)
                    {
                        var  isUntypedProp = readContext.GetType().GetProperty("IsUntyped", BindingFlags.NonPublic | BindingFlags.Instance);
                        bool isUntyped     = (bool)isUntypedProp.GetValue(readContext, null);
                        if (isUntyped)
                        {
                            EdmEntityObjectCollection entityCollection = new EdmEntityObjectCollection(feedType);
                            foreach (EdmEntityObject entityObject in enumerable)
                            {
                                entityCollection.Add(entityObject);
                            }

                            payload[parameterName] = entityCollection;
                        }
                        else
                        {
                            Type        elementClrType = EdmLibHelpers.GetClrType(elementTypeReference, readContext.Model);
                            IEnumerable castedResult   =
                                _castMethodInfo.MakeGenericMethod(elementClrType)
                                .Invoke(null, new[] { result }) as IEnumerable;
                            payload[parameterName] = castedResult;
                        }
                    }
                    break;
                }
            }

            return(payload);
        }