private static object ConvertEnumValue(ODataEnumValue enumValue, ref IEdmTypeReference propertyType,
                                               ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)
        {
            IEdmEnumTypeReference edmEnumType;

            if (propertyType == null)
            {
                // dynamic enum property
                Contract.Assert(!String.IsNullOrEmpty(enumValue.TypeName),
                                "ODataLib should have verified that dynamic enum value has a type name since we provided metadata.");
                IEdmModel model   = readContext.Model;
                IEdmType  edmType = model.FindType(enumValue.TypeName);
                Contract.Assert(edmType.TypeKind == EdmTypeKind.Enum, "ODataLib should have verified that enum value has a enum resource type.");
                edmEnumType  = new EdmEnumTypeReference(edmType as IEdmEnumType, isNullable: true);
                propertyType = edmEnumType;
            }
            else
            {
                edmEnumType = propertyType.AsEnum();
            }

            ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(edmEnumType);

            return(deserializer.ReadInline(enumValue, propertyType, readContext));
        }
        private static object ConvertCollectionValue(ODataCollectionValue collection,
                                                     ref IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider,
                                                     ODataDeserializerContext readContext)
        {
            IEdmCollectionTypeReference collectionType;

            if (propertyType == null)
            {
                // dynamic collection property
                Contract.Assert(!String.IsNullOrEmpty(collection.TypeName),
                                "ODataLib should have verified that dynamic collection value has a type name " +
                                "since we provided metadata.");

                string         elementTypeName = GetCollectionElementTypeName(collection.TypeName, isNested: false);
                IEdmModel      model           = readContext.Model;
                IEdmSchemaType elementType     = model.FindType(elementTypeName);
                Contract.Assert(elementType != null);
                collectionType =
                    new EdmCollectionTypeReference(
                        new EdmCollectionType(elementType.ToEdmTypeReference(isNullable: false)));
                propertyType = collectionType;
            }
            else
            {
                collectionType = propertyType as IEdmCollectionTypeReference;
                Contract.Assert(collectionType != null, "The type for collection must be a IEdmCollectionType.");
            }

            ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(collectionType);

            return(deserializer.ReadInline(collection, collectionType, readContext));
        }
Beispiel #3
0
        /// <summary>
        /// Reads Parameter names and values provided by a client in a POST request to invoke a particular Action.
        /// </summary>
        /// <param name="messageReader">Reader used to read all OData payloads (entries, feeds, metadata documents, service documents, etc.).</param>
        /// <param name="action">Represents an EDM operation.</param>
        /// <param name="readContext">
        /// Encapsulates the state and settings that get passed to System.Web.OData.Formatter.Deserialization.ODataDeserializer from the System.Web.OData.Formatter.ODataMediaTypeFormatter.
        /// </param>
        /// <returns>ActionPayload holds the Parameter names and values provided by a client in a POST request to invoke a particular Action.</returns>
        private ODataActionParameters ReadParams(ODataMessageReader messageReader, IEdmOperation action, ODataDeserializerContext readContext)
        {
            // Create the correct resource type;
            ODataActionParameters payload = new ODataActionParameters();

            try
            {
                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 = DefaultODataDeserializerProvider.Instance.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 = DefaultODataDeserializerProvider.Instance.GetEdmTypeDeserializer(collectionType) as ODataCollectionDeserializer;
                        payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext);
                        break;

                    default:
                        break;
                    }
                }
            }
            catch (Exception exception)
            {
                DynamicLogger.Instance.WriteLoggerLogError("ReadParams", exception);
                throw;
            }

            return(payload);
        }
        internal static object ConvertValue(
            object odataValue,
            Type expectedReturnType,
            IEdmTypeReference propertyType,
            IEdmModel model,
            ApiContext apiContext)
        {
            ODataDeserializerContext readContext = new ODataDeserializerContext
            {
                Model = model
            };

            ODataDeserializerProvider deserializerProvider = apiContext.GetApiService <ODataDeserializerProvider>();

            if (odataValue == null)
            {
                return(null);
            }

            ODataNullValue nullValue = odataValue as ODataNullValue;

            if (nullValue != null)
            {
                return(null);
            }

            ODataComplexValue complexValue = odataValue as ODataComplexValue;

            if (complexValue != null)
            {
                ODataEdmTypeDeserializer deserializer
                    = deserializerProvider.GetEdmTypeDeserializer(propertyType.AsComplex());
                return(deserializer.ReadInline(complexValue, propertyType, readContext));
            }

            ODataEnumValue enumValue = odataValue as ODataEnumValue;

            if (enumValue != null)
            {
                ODataEdmTypeDeserializer deserializer
                    = deserializerProvider.GetEdmTypeDeserializer(propertyType.AsEnum());
                return(deserializer.ReadInline(enumValue, propertyType, readContext));
            }

            ODataCollectionValue collection = odataValue as ODataCollectionValue;

            if (collection != null)
            {
                ODataEdmTypeDeserializer deserializer
                    = deserializerProvider.GetEdmTypeDeserializer(propertyType as IEdmCollectionTypeReference);
                var collectionResult = deserializer.ReadInline(collection, propertyType, readContext);

                return(ConvertCollectionType(collectionResult, expectedReturnType));
            }

            return(odataValue);
        }
Beispiel #5
0
        /// <summary>
        /// Override this method to translate property values in v3 format to v4 format.
        /// We treat collections (arrays of non-entity/non-complex types) differently from resource sets because
        /// there is an accessible method to override that allows us to examine each value in the collection and convert it if necessary.
        /// </summary>
        /// <param name="collectionValue">Each value in the collection</param>
        /// <param name="elementType">The type of the value</param>
        /// <param name="readContext">Context that contains model, state and HTTP request information</param>
        /// <returns>Deserialized object from request body</returns>
        public override IEnumerable ReadCollectionValue(ODataCollectionValue collectionValue, IEdmTypeReference elementType,
                                                        ODataDeserializerContext readContext)
        {
            if (collectionValue == null)
            {
                throw new ArgumentNullException(nameof(collectionValue));
            }

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

            ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(elementType);

            if (deserializer == null)
            {
                throw new SerializationException("Type " + elementType.FullName() + " cannot be deserialized");
            }

            foreach (object item in collectionValue.Items)
            {
                if (elementType.IsPrimitive())
                {
                    if (((IEdmPrimitiveType)elementType.Definition).PrimitiveKind == EdmPrimitiveTypeKind.Int64)
                    {
                        yield return(Convert.ToInt64(item));
                    }
                    else
                    {
                        yield return(item);
                    }
                }
                else
                {
                    yield return(deserializer.ReadInline(item, elementType, readContext));
                }
            }
        }
        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);
        }