private static void FillParameters(IEdmModel edmModel, List <KeyValuePair <String, Object> > parameters, Stream requestStream, IEdmOperation operation, String contentType)
        {
            if (!operation.Parameters.Any())
            {
                return;
            }

            IODataRequestMessage requestMessage = new Infrastructure.OeInMemoryMessage(requestStream, contentType);
            var settings = new ODataMessageReaderSettings()
            {
                EnableMessageStreamDisposal = false
            };

            using (var messageReader = new ODataMessageReader(requestMessage, settings, edmModel))
            {
                ODataParameterReader parameterReader = messageReader.CreateODataParameterReader(operation);
                while (parameterReader.Read())
                {
                    Object value;
                    switch (parameterReader.State)
                    {
                    case ODataParameterReaderState.Value:
                    {
                        value = OeEdmClrHelper.GetValue(edmModel, parameterReader.Value);
                        break;
                    }

                    case ODataParameterReaderState.Collection:
                    {
                        ODataCollectionReader collectionReader = parameterReader.CreateCollectionReader();
                        value = OeEdmClrHelper.GetValue(edmModel, ReadCollection(collectionReader));
                        break;
                    }

                    case ODataParameterReaderState.Resource:
                    {
                        ODataReader reader = parameterReader.CreateResourceReader();
                        value = OeEdmClrHelper.GetValue(edmModel, ReadResource(reader));
                        break;
                    }

                    case ODataParameterReaderState.ResourceSet:
                    {
                        ODataReader reader = parameterReader.CreateResourceSetReader();
                        value = OeEdmClrHelper.GetValue(edmModel, ReadResourceSet(reader));
                        break;
                    }

                    default:
                        continue;
                    }

                    parameters.Add(new KeyValuePair <String, Object>(parameterReader.Name, value));
                }
            }
        }
示例#2
0
        /// <inheritdoc />
        public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

            // Create the correct resource type;
            ODataActionParameters payload = new ODataActionParameters();

            IEdmFunctionImport   action = GetFunctionImport(readContext);
            ODataParameterReader reader = messageReader.CreateODataParameterReader(action);

            while (reader.Read())
            {
                string parameterName            = null;
                IEdmFunctionParameter 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));
                    payload[parameterName] = Convert(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);

                    payload[parameterName] = Convert(reader.CreateCollectionReader(), collectionType, readContext);
                    break;

                default:
                    break;
                }
            }

            return(payload);
        }
示例#3
0
        protected override object Read(System.Data.Services.SegmentInfo segmentInfo)
        {
            Func <OperationParameter, bool> predicate  = null;
            Func <OperationParameter, bool> func2      = null;
            IEdmFunctionImport          functionImport = base.GetFunctionImport(segmentInfo.Operation);
            ODataParameterReader        reader         = base.MessageReader.CreateODataParameterReader(functionImport);
            Dictionary <string, object> dictionary     = new Dictionary <string, object>(EqualityComparer <string> .Default);

            while (reader.Read())
            {
                ResourceType parameterType;
                object       obj2;
                switch (reader.State)
                {
                case ODataParameterReaderState.Value:
                    if (predicate == null)
                    {
                        predicate = p => p.Name == reader.Name;
                    }
                    parameterType = segmentInfo.Operation.Parameters.Single <OperationParameter>(predicate).ParameterType;
                    obj2          = base.ConvertValue(reader.Value, ref parameterType);
                    break;

                case ODataParameterReaderState.Collection:
                {
                    ODataCollectionReader collectionReader = reader.CreateCollectionReader();
                    if (func2 == null)
                    {
                        func2 = p => p.Name == reader.Name;
                    }
                    parameterType = segmentInfo.Operation.Parameters.Single <OperationParameter>(func2).ParameterType;
                    obj2          = base.ConvertValue(ReadCollectionParameterValue(collectionReader), ref parameterType);
                    break;
                }

                case ODataParameterReaderState.Completed:
                    return(dictionary);

                default:
                    throw new InvalidOperationException(System.Data.Services.Strings.DataServiceException_GeneralError);
                }
                dictionary.Add(reader.Name, obj2);
            }
            return(dictionary);
        }
示例#4
0
        private static OeSkipTokenNameValue[] ParseJson(IEdmModel edmModel, String skipToken, IEdmStructuralProperty[] keys, out int?restCount)
        {
            restCount = null;
            var skipTokenNameValues = new OeSkipTokenNameValue[keys.Length];

            using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(skipToken)))
            {
                IODataRequestMessage requestMessage = new Infrastructure.OeInMemoryMessage(stream, null);
                using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, ReaderSettings, edmModel))
                {
                    var operation = new EdmAction("", "", null);
                    foreach (IEdmStructuralProperty key in keys)
                    {
                        operation.AddParameter(GetPropertyName(key), key.Type);
                    }
                    operation.AddParameter(RestCountName, OeEdmClrHelper.GetEdmTypeReference(edmModel, typeof(int?)));

                    ODataParameterReader reader = messageReader.CreateODataParameterReader(operation);
                    int i = 0;
                    while (reader.Read())
                    {
                        Object value = reader.Value;
                        if (value is ODataEnumValue enumValue)
                        {
                            value = OeEdmClrHelper.GetValue(edmModel, enumValue);
                        }

                        if (reader.Name == RestCountName)
                        {
                            restCount = (int)value;
                        }
                        else
                        {
                            skipTokenNameValues[i++] = new OeSkipTokenNameValue(reader.Name, value);
                        }
                    }
                }
            }
            return(skipTokenNameValues);
        }
        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 = GetPayload(type, action);

            ODataParameterReader reader = messageReader.CreateODataParameterReader(action);

            while (reader.Read())
            {
                switch (reader.State)
                {
                case ODataParameterReaderState.Value:
                    ReadValue(action, reader, readContext, DeserializerProvider, payload);
                    break;

                case ODataParameterReaderState.Collection:
                    ReadCollection(action, reader, readContext, DeserializerProvider, payload);
                    break;

                case ODataParameterReaderState.Resource:
                    ReadResource(action, reader, readContext, DeserializerProvider, payload);
                    break;

                case ODataParameterReaderState.ResourceSet:
                    ReadResourceSet(action, reader, readContext, DeserializerProvider, payload);
                    break;
                }
            }

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

            IEdmFunctionImport action = GetFunctionImport(readContext);

            // 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;
                IEdmFunctionParameter 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 = ODataCollectionDeserializer.ReadCollection(reader.CreateCollectionReader());
                    ODataCollectionDeserializer collectionDeserializer = DeserializerProvider.GetEdmTypeDeserializer(collectionType) as ODataCollectionDeserializer;
                    payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext);
                    break;

                default:
                    break;
                }
            }

            return(payload);
        }
        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 = ODataCollectionDeserializer.ReadCollection(reader.CreateCollectionReader());
                    ODataCollectionDeserializer collectionDeserializer = (ODataCollectionDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType);
                    payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext);
                    break;

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

                    ODataReader resourceReader = reader.CreateResourceReader();
                    object      item           = resourceReader.ReadResourceOrResourceSet();
                    ODataResourceDeserializer resourceDeserializer = (ODataResourceDeserializer)DeserializerProvider.GetEdmTypeDeserializer(parameter.Type);
                    payload[parameterName] = resourceDeserializer.ReadInline(item, parameter.Type, readContext);
                    break;

                case ODataParameterReaderState.ResourceSet:
                    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 resourceSetType = parameter.Type as IEdmCollectionTypeReference;
                    Contract.Assert(resourceSetType != null);

                    ODataReader resourceSetReader = reader.CreateResourceSetReader();
                    object      feed = resourceSetReader.ReadResourceOrResourceSet();
                    ODataResourceSetDeserializer resourceSetDeserializer = (ODataResourceSetDeserializer)DeserializerProvider.GetEdmTypeDeserializer(resourceSetType);

                    object result = resourceSetDeserializer.ReadInline(feed, resourceSetType, readContext);

                    IEdmTypeReference elementTypeReference = resourceSetType.ElementType();
                    Contract.Assert(elementTypeReference.IsStructured());

                    IEnumerable enumerable = result as IEnumerable;
                    if (enumerable != null)
                    {
                        if (readContext.IsUntyped)
                        {
                            payload[parameterName] = enumerable.ConvertToEdmObject(resourceSetType);
                        }
                        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);
        }
示例#8
0
        public void ParameterReaderCreateReaderStateMachineTests()
        {
            IEdmModel           model = TestModels.BuildModelWithFunctionImport();
            IEdmOperationImport functionImport_Primitive           = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Primitive").First();
            IEdmOperationImport functionImport_PrimitiveCollection = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_PrimitiveCollection").First();
            IEdmOperationImport functionImport_Complex             = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Complex").First();
            IEdmOperationImport functionImport_ComplexCollection   = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_ComplexCollection").First();
            IEdmOperationImport functionImport_Entry = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Entry").First();
            IEdmOperationImport functionImport_Feed  = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Feed").First();

            CreateReaderMethods[] createReaderMethods = new CreateReaderMethods[]
            {
                CreateReaderMethods.CreateCollectionReader,
            };

            var testConfigurations = this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(c => c.IsRequest);

            this.CombinatorialEngineProvider.RunCombinations(
                testConfigurations,
                createReaderMethods,
                (testConfiguration, createReaderMethod) =>
            {
                // Calling Create*Reader in Start state should fail.
                ODataParameterReader reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Complex, testConfiguration, "{ complex : { PrimitiveProperty : \"456\" } }");
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, createReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Start.ToString()), this.ExceptionVerifier);
                this.Assert.AreEqual(ODataParameterReaderState.Start, reader.State, "Unexpected parameter reader state.");

                // Calling Create*Reader in Value state should fail.
                reader.Read();
                this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state.");
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, createReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Resource.ToString()), this.ExceptionVerifier);
                this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state.");

                if (createReaderMethod != CreateReaderMethods.CreateResourceReader)
                {
                    // Calling Create*Reader in Entry state should fail.
                    reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Entry, testConfiguration, "{ entry : {} }");
                    reader.Read();
                    this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state.");
                    this.Assert.ExpectedException(
                        () => CreateSubReader(reader, createReaderMethod),
                        ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Resource.ToString()), this.ExceptionVerifier);
                    this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state.");
                }

                if (createReaderMethod != CreateReaderMethods.CreateResourceSetReader)
                {
                    // Calling Create*Reader in Feed state should fail.
                    reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Feed, testConfiguration, "{ feed : [] }");
                    reader.Read();
                    this.Assert.AreEqual(ODataParameterReaderState.ResourceSet, reader.State, "Unexpected parameter reader state.");
                    this.Assert.ExpectedException(
                        () => CreateSubReader(reader, createReaderMethod),
                        ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.ResourceSet.ToString()), this.ExceptionVerifier);
                    this.Assert.AreEqual(ODataParameterReaderState.ResourceSet, reader.State, "Unexpected parameter reader state.");
                }

                if (createReaderMethod != CreateReaderMethods.CreateCollectionReader)
                {
                    // Calling Create*Reader in Collection state should fail.
                    reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_ComplexCollection, testConfiguration, "{ complexCollection : [] }");
                    reader.Read();
                    this.Assert.AreEqual(ODataParameterReaderState.Collection, reader.State, "Unexpected parameter reader state.");
                    this.Assert.ExpectedException(
                        () => CreateSubReader(reader, createReaderMethod),
                        ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Collection.ToString()), this.ExceptionVerifier);
                    this.Assert.AreEqual(ODataParameterReaderState.Collection, reader.State, "Unexpected parameter reader state.");
                }

                // Calling Read() in Entry/Feed/Collection state without calling Create***Reader should fail.
                IEdmOperationImport functionImport = createReaderMethod == CreateReaderMethods.CreateResourceReader ? functionImport_Entry : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? functionImport_Feed : functionImport_ComplexCollection);
                string payload = createReaderMethod == CreateReaderMethods.CreateResourceReader ? "{ entry : {} }" : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? "{ feed : [] }" : "{ complexCollection : [] }");
                ODataParameterReaderState expectedParameterState = createReaderMethod == CreateReaderMethods.CreateResourceReader ? ODataParameterReaderState.Resource : ODataParameterReaderState.ResourceSet;
                var expectedReaderMethod = createReaderMethod == CreateReaderMethods.CreateCollectionReader ? CreateReaderMethods.CreateResourceSetReader.ToString() : createReaderMethod.ToString();
                reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport, testConfiguration, payload);
                reader.Read();
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");
                this.Assert.ExpectedException(
                    () => reader.Read(),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_SubReaderMustBeCreatedAndReadToCompletionBeforeTheNextReadOrReadAsyncCall", expectedParameterState.ToString(), expectedReaderMethod), this.ExceptionVerifier);
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");

                // Calling Read() in Entry/Feed/Collection state after Create***Reader() is called but before the created reader finishes should fail.
                var subReaderMethod = createReaderMethod == CreateReaderMethods.CreateCollectionReader
                        ? CreateReaderMethods.CreateResourceSetReader : createReaderMethod;
                object subReader = CreateSubReader(reader,
                                                   subReaderMethod);
                this.Assert.ExpectedException(
                    () => reader.Read(),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_SubReaderMustBeInCompletedStateBeforeTheNextReadOrReadAsyncCall", expectedParameterState.ToString(), expectedReaderMethod), this.ExceptionVerifier);
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");

                // Calling Create*Reader() before the sub-reader is completed should fail.
                string parameterName = createReaderMethod == CreateReaderMethods.CreateResourceReader ? "entry" : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? "feed" : "complexCollection");
                subReader.GetType().GetMethod("Read").Invoke(subReader, null);
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, subReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_CreateReaderAlreadyCalled", expectedReaderMethod, parameterName), this.ExceptionVerifier);
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");

                // Calling Create*Reader() after sub-reader is completed should fail.
                while ((bool)subReader.GetType().GetMethod("Read").Invoke(subReader, null))
                {
                    ;
                }
                this.Assert.AreEqual("Completed", subReader.GetType().GetProperty("State").GetValue(subReader, null).ToString(), "Unexpected sub-reader state.");
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, subReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_CreateReaderAlreadyCalled", expectedReaderMethod, parameterName), this.ExceptionVerifier);
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");

                // Finish reading...
                reader.Read();
                this.Assert.AreEqual(ODataParameterReaderState.Completed, reader.State, "Unexpected parameter reader state.");

                // Calling Create*Reader in Completed state should fail.
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, subReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", expectedReaderMethod, ODataParameterReaderState.Completed.ToString()), this.ExceptionVerifier);
                this.Assert.AreEqual(ODataParameterReaderState.Completed, reader.State, "Unexpected parameter reader state.");

                // Exception in subReader should put parent reader in Exception state.
                payload = createReaderMethod == CreateReaderMethods.CreateResourceReader ? "{ entry : \"foo\" }" : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? "{ feed : { \"foo\" : \"bar\" } }" : "{ complexCollection : { \"foo\" : \"bar\" } }");
                reader  = this.CreateParameterReaderForRequestOrResponse(model, functionImport, testConfiguration, payload);
                reader.Read();
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");
                subReader = CreateSubReader(reader, subReaderMethod);
                this.Assert.IsNotNull(TestExceptionUtils.RunCatching(() => { while ((bool)subReader.GetType().GetMethod("Read").Invoke(subReader, null))
                                                                             {
                                                                             }
                                                                     }), "Expecting sub-reader.Read() to fail.");
                this.Assert.AreEqual("Exception", subReader.GetType().GetProperty("State").GetValue(subReader, null).ToString(), "Unexpected sub-reader state.");
                this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Unexpected parameter reader state.");

                // Calling Create*Reader in Exception state should fail.
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, subReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", expectedReaderMethod, ODataParameterReaderState.Exception.ToString()), this.ExceptionVerifier);
                this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Unexpected parameter reader state.");
            });
        }
        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);
        }