private async Task WriteOperationParameterAsync(ODataParameterWriter parameterWriter, IEdmOperationParameter operationParameter, string paramName, object paramValue)
        {
            switch (operationParameter.Type.Definition.TypeKind)
            {
            case EdmTypeKind.Primitive:
                var value = GetPropertyValue(operationParameter.Type, paramValue, null);
                await parameterWriter.WriteValueAsync(paramName, value).ConfigureAwait(false);

                break;

            case EdmTypeKind.Enum:
                await parameterWriter.WriteValueAsync(paramName, new ODataEnumValue(paramValue.ToString())).ConfigureAwait(false);

                break;

            case EdmTypeKind.Untyped:
                await parameterWriter.WriteValueAsync(paramName, new ODataUntypedValue { RawValue = paramValue.ToString() }).ConfigureAwait(false);

                break;

            case EdmTypeKind.Entity:
            {
                var entryWriter = await parameterWriter.CreateResourceWriterAsync(paramName).ConfigureAwait(false);

                var paramValueDict = paramValue.ToDictionary(TypeCache);
                var contentId      = _deferredBatchWriter?.Value.GetContentId(paramValueDict, null);

                var typeName = operationParameter.Type.Definition.FullTypeName();
                if (paramValueDict.ContainsKey("@odata.type") && paramValueDict["@odata.type"] is string)
                {
                    typeName = paramValueDict["@odata.type"] as string;
                    paramValueDict.Remove("@odata.type");
                }

                var entryDetails = _session.Metadata.ParseEntryDetails(typeName, paramValueDict, contentId);
                var entry        = CreateODataEntry(typeName, entryDetails.Properties, null);

                RegisterRootEntry(entry);
                await WriteEntryPropertiesAsync(entryWriter, entry, entryDetails.Links).ConfigureAwait(false);

                UnregisterRootEntry(entry);
            }
            break;

            case EdmTypeKind.Complex:
            {
                var entryWriter = await parameterWriter.CreateResourceWriterAsync(paramName).ConfigureAwait(false);

                var paramValueDict = paramValue.ToDictionary(TypeCache);

                var typeName = operationParameter.Type.Definition.FullTypeName();
                if (paramValueDict.ContainsKey("@odata.type") && paramValueDict["@odata.type"] is string)
                {
                    typeName = paramValueDict["@odata.type"] as string;
                    paramValueDict.Remove("@odata.type");
                }

                var entry = CreateODataEntry(typeName, paramValueDict, null);

                RegisterRootEntry(entry);
                await WriteEntryPropertiesAsync(entryWriter, entry, new Dictionary <string, List <ReferenceLink> >()).ConfigureAwait(false);

                UnregisterRootEntry(entry);
            }
            break;

            case EdmTypeKind.Collection:
                var collectionType = operationParameter.Type.Definition as IEdmCollectionType;
                var elementType    = collectionType.ElementType;
                if (elementType.Definition.TypeKind == EdmTypeKind.Entity)
                {
                    var feedWriter = await parameterWriter.CreateResourceSetWriterAsync(paramName).ConfigureAwait(false);

                    var feed = new ODataResourceSet();
                    await feedWriter.WriteStartAsync(feed).ConfigureAwait(false);

                    foreach (var item in (IEnumerable)paramValue)
                    {
                        var feedEntry = CreateODataEntry(elementType.Definition.FullTypeName(), item.ToDictionary(TypeCache), null);

                        RegisterRootEntry(feedEntry);
                        await feedWriter.WriteStartAsync(feedEntry).ConfigureAwait(false);

                        await feedWriter.WriteEndAsync().ConfigureAwait(false);

                        UnregisterRootEntry(feedEntry);
                    }
                    await feedWriter.WriteEndAsync().ConfigureAwait(false);
                }
                else
                {
                    var collectionWriter = await parameterWriter.CreateCollectionWriterAsync(paramName).ConfigureAwait(false);

                    await collectionWriter.WriteStartAsync(new ODataCollectionStart()).ConfigureAwait(false);

                    foreach (var item in (IEnumerable)paramValue)
                    {
                        await collectionWriter.WriteItemAsync(item).ConfigureAwait(false);
                    }
                    await collectionWriter.WriteEndAsync().ConfigureAwait(false);
                }
                break;

            default:
                throw new NotSupportedException($"Unable to write action parameter of a type {operationParameter.Type.Definition.TypeKind}");
            }
        }
        private async Task WriteOperationParameterAsync(ODataParameterWriter parameterWriter, IEdmOperationParameter operationParameter, string paramName, object paramValue)
        {
            switch (operationParameter.Type.Definition.TypeKind)
            {
            case EdmTypeKind.Primitive:
            case EdmTypeKind.Complex:
                var value = GetPropertyValue(operationParameter.Type, paramValue, null);
                await parameterWriter.WriteValueAsync(paramName, value).ConfigureAwait(false);

                break;

            case EdmTypeKind.Enum:
                await parameterWriter.WriteValueAsync(paramName, new ODataEnumValue(paramValue.ToString())).ConfigureAwait(false);

                break;

            case EdmTypeKind.Untyped:
                await parameterWriter.WriteValueAsync(paramName, new ODataUntypedValue { RawValue = paramValue.ToString() }).ConfigureAwait(false);

                break;

            case EdmTypeKind.Entity:
                var entryWriter = await parameterWriter.CreateResourceWriterAsync(paramName).ConfigureAwait(false);

                var entry = CreateODataEntry(operationParameter.Type.Definition.FullTypeName(), paramValue.ToDictionary(), null);

                RegisterRootEntry(entry);
                await entryWriter.WriteStartAsync(entry).ConfigureAwait(false);

                await entryWriter.WriteEndAsync().ConfigureAwait(false);

                UnregisterRootEntry(entry);

                break;

            case EdmTypeKind.Collection:
                var collectionType = operationParameter.Type.Definition as IEdmCollectionType;
                var elementType    = collectionType.ElementType;
                if (elementType.Definition.TypeKind == EdmTypeKind.Entity)
                {
                    var feedWriter = await parameterWriter.CreateResourceSetWriterAsync(paramName).ConfigureAwait(false);

                    var feed = new ODataResourceSet();
                    await feedWriter.WriteStartAsync(feed).ConfigureAwait(false);

                    foreach (var item in (IEnumerable)paramValue)
                    {
                        var feedEntry = CreateODataEntry(elementType.Definition.FullTypeName(), item.ToDictionary(), null);

                        RegisterRootEntry(feedEntry);
                        await feedWriter.WriteStartAsync(feedEntry).ConfigureAwait(false);

                        await feedWriter.WriteEndAsync().ConfigureAwait(false);

                        UnregisterRootEntry(feedEntry);
                    }
                    await feedWriter.WriteEndAsync().ConfigureAwait(false);
                }
                else
                {
                    var collectionWriter = await parameterWriter.CreateCollectionWriterAsync(paramName).ConfigureAwait(false);

                    await collectionWriter.WriteStartAsync(new ODataCollectionStart()).ConfigureAwait(false);

                    foreach (var item in (IEnumerable)paramValue)
                    {
                        await collectionWriter.WriteItemAsync(item).ConfigureAwait(false);
                    }
                    await collectionWriter.WriteEndAsync().ConfigureAwait(false);
                }
                break;

            default:
                throw new NotSupportedException($"Unable to write action parameter of a type {operationParameter.Type.Definition.TypeKind}");
            }
        }
Esempio n. 3
0
        internal void WriteBodyOperationParameters(List <BodyOperationParameter> operationParameters, ODataRequestMessageWrapper requestMessage)
        {
            using (ODataMessageWriter writer = CreateMessageWriter(requestMessage, this.requestInfo))
            {
                ODataParameterWriter writer2 = writer.CreateODataParameterWriter(null);
                writer2.WriteStart();
                foreach (OperationParameter parameter in operationParameters)
                {
                    IEnumerator           enumerator;
                    ODataCollectionWriter writer3;
                    object obj2;
                    if (parameter.Value == null)
                    {
                        writer2.WriteValue(parameter.Name, parameter.Value);
                        continue;
                    }
                    ClientEdmModel model           = ClientEdmModel.GetModel(this.requestInfo.MaxProtocolVersion);
                    IEdmType       orCreateEdmType = model.GetOrCreateEdmType(parameter.Value.GetType());
                    switch (orCreateEdmType.TypeKind)
                    {
                    case EdmTypeKind.Primitive:
                    {
                        writer2.WriteValue(parameter.Name, parameter.Value);
                        continue;
                    }

                    case EdmTypeKind.Complex:
                    {
                        ODataComplexValue parameterValue = this.CreateODataComplexValue(model.GetClientTypeAnnotation(orCreateEdmType).ElementType, parameter.Value, null, false, null);
                        writer2.WriteValue(parameter.Name, parameterValue);
                        continue;
                    }

                    case EdmTypeKind.Collection:
                    {
                        enumerator = ((ICollection)parameter.Value).GetEnumerator();
                        writer3    = writer2.CreateCollectionWriter(parameter.Name);
                        ODataCollectionStart collectionStart = new ODataCollectionStart();
                        writer3.WriteStart(collectionStart);
                        goto Label_016D;
                    }

                    default:
                        throw new NotSupportedException(System.Data.Services.Client.Strings.Serializer_InvalidParameterType(parameter.Name, orCreateEdmType.TypeKind));
                    }
Label_00D3:
                    obj2 = enumerator.Current;
                    if (obj2 == null)
                    {
                        throw new NotSupportedException(System.Data.Services.Client.Strings.Serializer_NullCollectionParamterItemValue(parameter.Name));
                    }
                    IEdmType edmType = model.GetOrCreateEdmType(obj2.GetType());
                    switch (edmType.TypeKind)
                    {
                    case EdmTypeKind.Primitive:
                        writer3.WriteItem(obj2);
                        break;

                    case EdmTypeKind.Complex:
                    {
                        ODataComplexValue item = this.CreateODataComplexValue(model.GetClientTypeAnnotation(edmType).ElementType, obj2, null, false, null);
                        writer3.WriteItem(item);
                        break;
                    }

                    default:
                        throw new NotSupportedException(System.Data.Services.Client.Strings.Serializer_InvalidCollectionParamterItemType(parameter.Name, edmType.TypeKind));
                    }
Label_016D:
                    if (enumerator.MoveNext())
                    {
                        goto Label_00D3;
                    }
                    writer3.WriteEnd();
                    writer3.Flush();
                }
                writer2.WriteEnd();
                writer2.Flush();
            }
        }
        public void ParameterWriterStateMachineErrorTests()
        {
            var testCases = new ParameterWriterStateMachineTestCase[]
            {
                // WriteStart can only be called once and it must be called before writing anything else.
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteStart();
                        writer.WriteStart();
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteStart"),
                },
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteStart();
                        writer.WriteValue("p1", null);
                        writer.WriteStart();
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteStart"),
                },
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteStart();
                        writer.CreateCollectionWriter("p1");
                        writer.WriteStart();
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteStart"),
                },
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteStart();
                        writer.WriteEnd();
                        writer.WriteStart();
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteStart"),
                },

                // WriteValue and CreateCollectionWriter can only be called after WriteStart and before WriteEnd. And they cannot be called until the previously created sub-writer is completed.
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteValue("p1", null);
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteParameter"),
                },
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteStart();
                        writer.CreateCollectionWriter("p1");
                        writer.WriteValue("p1", null);
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteParameter"),
                },
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.CreateCollectionWriter("p1");
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteParameter"),
                },

                // WriteEnd can only be called after WriteStart and after the previously created sub-writer is completed.
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteEnd();
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteEnd"),
                },
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteStart();
                        writer.CreateCollectionWriter("p1");
                        writer.WriteEnd();
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteEnd"),
                },

                // The writer is in error or completed state. No further writes can be performed on this writer.
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteStart();
                        writer.WriteEnd();
                        writer.WriteValue("p1", null);
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteInErrorOrCompletedState"),
                },
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteStart();
                        writer.WriteEnd();
                        writer.CreateCollectionWriter("p1");
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteInErrorOrCompletedState"),
                },
                new ParameterWriterStateMachineTestCase
                {
                    WriteActions = writer =>
                    {
                        writer.WriteStart();
                        writer.WriteEnd();
                        writer.WriteEnd();
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataParameterWriterCore_CannotWriteInErrorOrCompletedState"),
                },
                // TODO: Add test cases to cause the writer enter error state then verify that no writes can be performed afterwards.
            };

            var testConfigurations = this.WriterTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => tc.IsRequest);

            this.CombinatorialEngineProvider.RunCombinations(testConfigurations, testCases, (testConfiguration, testCase) =>
            {
                PayloadWriterTestDescriptor.WriterTestExpectedResultCallback resultCallback = testConfig => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                {
                    ExpectedException2 = testCase.ExpectedException
                };
                var testDescriptor = new PayloadWriterTestDescriptor <ODataParameters>(this.Settings, ObjectModelUtils.CreateDefaultParameter(), resultCallback);

                TestWriterUtils.WriteActionAndVerifyODataPayload <ODataParameters>(
                    (messageWriter, writerDescriptor, feedWriter) =>
                {
                    ODataParameterWriter writer = messageWriter.CreateODataParameterWriter(null /*functionImport*/);
                    testCase.WriteActions(writer);
                },
                    testDescriptor,
                    testConfiguration,
                    this.Assert,
                    this.Logger);
            });
        }
Esempio n. 5
0
        /// <summary>
        /// Writes collection value in body operation parameter.
        /// </summary>
        /// <param name="parameterWriter">The odata parameter writer.</param>
        /// <param name="operationParameter">The operation parameter.</param>
        /// <param name="edmCollectionType">The edm collection type.</param>
        private void WriteCollectionValueInBodyOperationParameter(ODataParameterWriter parameterWriter, BodyOperationParameter operationParameter, IEdmCollectionType edmCollectionType)
        {
            ClientEdmModel model = this.requestInfo.Model;

            var elementTypeKind = edmCollectionType.ElementType.TypeKind();

            if (elementTypeKind == EdmTypeKind.Entity || elementTypeKind == EdmTypeKind.Complex)
            {
                ODataWriter feedWriter = parameterWriter.CreateResourceSetWriter(operationParameter.Name);
                feedWriter.WriteStart(new ODataResourceSet());

                IEnumerator enumerator = ((ICollection)operationParameter.Value).GetEnumerator();

                while (enumerator.MoveNext())
                {
                    Object collectionItem = enumerator.Current;
                    if (collectionItem == null)
                    {
                        if (elementTypeKind == EdmTypeKind.Complex)
                        {
                            feedWriter.WriteStart((ODataResource)null);
                            feedWriter.WriteEnd();
                            continue;
                        }
                        else
                        {
                            throw new NotSupportedException(Strings.Serializer_NullCollectionParamterItemValue(operationParameter.Name));
                        }
                    }

                    IEdmType edmItemType = model.GetOrCreateEdmType(collectionItem.GetType());
                    Debug.Assert(edmItemType != null, "edmItemType != null");

                    if (edmItemType.TypeKind != EdmTypeKind.Entity && edmItemType.TypeKind != EdmTypeKind.Complex)
                    {
                        throw new NotSupportedException(Strings.Serializer_InvalidCollectionParamterItemType(operationParameter.Name, edmItemType.TypeKind));
                    }

                    Debug.Assert(model.GetClientTypeAnnotation(edmItemType).ElementType != null, "edmItemType.GetClientTypeAnnotation().ElementType != null");
                    ODataResourceWrapper entry = this.CreateODataResourceFromEntityOperationParameter(model.GetClientTypeAnnotation(edmItemType), collectionItem);
                    Debug.Assert(entry != null, "entry != null");
                    ODataWriterHelper.WriteResource(feedWriter, entry);
                }

                feedWriter.WriteEnd();
                feedWriter.Flush();
            }
            else
            {
                ODataCollectionWriter collectionWriter     = parameterWriter.CreateCollectionWriter(operationParameter.Name);
                ODataCollectionStart  odataCollectionStart = new ODataCollectionStart();
                collectionWriter.WriteStart(odataCollectionStart);

                IEnumerator enumerator = ((ICollection)operationParameter.Value).GetEnumerator();

                while (enumerator.MoveNext())
                {
                    Object collectionItem = enumerator.Current;
                    if (collectionItem == null)
                    {
                        collectionWriter.WriteItem(null);
                        continue;
                    }

                    IEdmType edmItemType = model.GetOrCreateEdmType(collectionItem.GetType());
                    Debug.Assert(edmItemType != null, "edmItemType != null");

                    switch (edmItemType.TypeKind)
                    {
                    case EdmTypeKind.Primitive:
                    {
                        object primitiveItemValue = ODataPropertyConverter.ConvertPrimitiveValueToRecognizedODataType(collectionItem, collectionItem.GetType());
                        collectionWriter.WriteItem(primitiveItemValue);
                        break;
                    }

                    case EdmTypeKind.Enum:
                    {
                        ODataEnumValue enumTmp = this.propertyConverter.CreateODataEnumValue(model.GetClientTypeAnnotation(edmItemType).ElementType, collectionItem, false);
                        collectionWriter.WriteItem(enumTmp);
                        break;
                    }

                    default:
                        // EdmTypeKind.Entity
                        // EdmTypeKind.Row
                        // EdmTypeKind.EntityReference
                        throw new NotSupportedException(Strings.Serializer_InvalidCollectionParamterItemType(operationParameter.Name, edmItemType.TypeKind));
                    }
                }

                collectionWriter.WriteEnd();
                collectionWriter.Flush();
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Writes the body operation parameters associated with a ServiceAction. For each BodyOperationParameter:
        /// 1. calls ODataPropertyConverter  to convert CLR object into ODataValue/primitive values.
        /// 2. then calls ODataParameterWriter to write the ODataValue/primitive values.
        /// </summary>
        /// <param name="operationParameters">The list of operation parameters to write.</param>
        /// <param name="requestMessage">The OData request message used to write the operation parameters.</param>
        internal void WriteBodyOperationParameters(List <BodyOperationParameter> operationParameters, ODataRequestMessageWrapper requestMessage)
        {
            Debug.Assert(requestMessage != null, "requestMessage != null");
            Debug.Assert(operationParameters != null, "operationParameters != null");
            Debug.Assert(operationParameters.Any(), "operationParameters.Any()");

            using (ODataMessageWriter messageWriter = Serializer.CreateMessageWriter(requestMessage, this.requestInfo, true /*isParameterPayload*/))
            {
                ODataParameterWriter parameterWriter = messageWriter.CreateODataParameterWriter(null);
                parameterWriter.WriteStart();

                foreach (BodyOperationParameter operationParameter in operationParameters)
                {
                    if (operationParameter.Value == null)
                    {
                        parameterWriter.WriteValue(operationParameter.Name, operationParameter.Value);
                    }
                    else
                    {
                        ClientEdmModel model   = this.requestInfo.Model;
                        IEdmType       edmType = model.GetOrCreateEdmType(operationParameter.Value.GetType());
                        Debug.Assert(edmType != null, "edmType != null");

                        switch (edmType.TypeKind)
                        {
                        case EdmTypeKind.Collection:
                        {
                            this.WriteCollectionValueInBodyOperationParameter(parameterWriter, operationParameter, (IEdmCollectionType)edmType);
                            break;
                        }

                        case EdmTypeKind.Complex:
                        case EdmTypeKind.Entity:
                        {
                            Debug.Assert(model.GetClientTypeAnnotation(edmType).ElementType != null, "model.GetClientTypeAnnotation(edmType).ElementType != null");
                            ODataResourceWrapper entry = this.CreateODataResourceFromEntityOperationParameter(model.GetClientTypeAnnotation(edmType), operationParameter.Value);
                            Debug.Assert(entry != null, "entry != null");
                            var entryWriter = parameterWriter.CreateResourceWriter(operationParameter.Name);
                            ODataWriterHelper.WriteResource(entryWriter, entry);
                            break;
                        }

                        case EdmTypeKind.Primitive:
                            object primitiveValue = ODataPropertyConverter.ConvertPrimitiveValueToRecognizedODataType(operationParameter.Value, operationParameter.Value.GetType());
                            parameterWriter.WriteValue(operationParameter.Name, primitiveValue);
                            break;

                        case EdmTypeKind.Enum:
                            ODataEnumValue tmp = this.propertyConverter.CreateODataEnumValue(
                                model.GetClientTypeAnnotation(edmType).ElementType,
                                operationParameter.Value,
                                false);
                            parameterWriter.WriteValue(operationParameter.Name, tmp);

                            break;

                        default:
                            // EdmTypeKind.Row
                            // EdmTypeKind.EntityReference
                            throw new NotSupportedException(Strings.Serializer_InvalidParameterType(operationParameter.Name, edmType.TypeKind));
                        }
                    } // else
                }     // foreach

                parameterWriter.WriteEnd();
                parameterWriter.Flush();
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Writes the body operation parameters associated with a ServiceAction. For each BodyOperationParameter:
        /// 1. calls ODataPropertyConverter  to convert CLR object into ODataValue/primitive values.
        /// 2. then calls ODataParameterWriter to write the ODataValue/primitive values.
        /// </summary>
        /// <param name="operationParameters">The list of operation parameters to write.</param>
        /// <param name="requestMessage">The OData request message used to write the operation parameters.</param>
        internal void WriteBodyOperationParameters(List <BodyOperationParameter> operationParameters, ODataRequestMessageWrapper requestMessage)
        {
            Debug.Assert(requestMessage != null, "requestMessage != null");
            Debug.Assert(operationParameters != null, "operationParameters != null");
            Debug.Assert(operationParameters.Any(), "operationParameters.Any()");

            using (ODataMessageWriter messageWriter = Serializer.CreateMessageWriter(requestMessage, this.requestInfo, true /*isParameterPayload*/))
            {
                ODataParameterWriter parameterWriter = messageWriter.CreateODataParameterWriter((IEdmOperation)null);
                parameterWriter.WriteStart();

                foreach (OperationParameter operationParameter in operationParameters)
                {
                    if (operationParameter.Value == null)
                    {
                        parameterWriter.WriteValue(operationParameter.Name, operationParameter.Value);
                    }
                    else
                    {
                        ClientEdmModel model   = this.requestInfo.Model;
                        IEdmType       edmType = model.GetOrCreateEdmType(operationParameter.Value.GetType());
                        Debug.Assert(edmType != null, "edmType != null");

                        switch (edmType.TypeKind)
                        {
                        case EdmTypeKind.Collection:
                        {
                            // TODO: just call ODataPropertyConverter.CreateODataCollection()
                            IEnumerator           enumerator           = ((ICollection)operationParameter.Value).GetEnumerator();
                            ODataCollectionWriter collectionWriter     = parameterWriter.CreateCollectionWriter(operationParameter.Name);
                            ODataCollectionStart  odataCollectionStart = new ODataCollectionStart();
                            collectionWriter.WriteStart(odataCollectionStart);

                            while (enumerator.MoveNext())
                            {
                                Object collectionItem = enumerator.Current;
                                if (collectionItem == null)
                                {
                                    throw new NotSupportedException(Strings.Serializer_NullCollectionParamterItemValue(operationParameter.Name));
                                }

                                IEdmType edmItemType = model.GetOrCreateEdmType(collectionItem.GetType());
                                Debug.Assert(edmItemType != null, "edmItemType != null");

                                switch (edmItemType.TypeKind)
                                {
                                case EdmTypeKind.Complex:
                                {
                                    Debug.Assert(model.GetClientTypeAnnotation(edmItemType).ElementType != null, "edmItemType.GetClientTypeAnnotation().ElementType != null");
                                    ODataComplexValue complexValue = this.propertyConverter.CreateODataComplexValue(
                                        model.GetClientTypeAnnotation(edmItemType).ElementType,
                                        collectionItem,
                                        null /*propertyName*/,
                                        false /*isCollectionItem*/,
                                        null /*visitedComplexTypeObjects*/);

                                    Debug.Assert(complexValue != null, "complexValue != null");
                                    collectionWriter.WriteItem(complexValue);
                                    break;
                                }

                                case EdmTypeKind.Primitive:
                                {
                                    object primitiveItemValue = ODataPropertyConverter.ConvertPrimitiveValueToRecognizedODataType(collectionItem, collectionItem.GetType());
                                    collectionWriter.WriteItem(primitiveItemValue);
                                    break;
                                }

                                case EdmTypeKind.Enum:
                                {
                                    ODataEnumValue enumTmp = this.propertyConverter.CreateODataEnumValue(
                                        model.GetClientTypeAnnotation(edmItemType).ElementType,
                                        collectionItem,
                                        false);
                                    collectionWriter.WriteItem(enumTmp);
                                    break;
                                }

                                default:

                                    // EdmTypeKind.Entity
                                    // EdmTypeKind.Row
                                    // EdmTypeKind.EntityReference
                                    throw new NotSupportedException(Strings.Serializer_InvalidCollectionParamterItemType(operationParameter.Name, edmItemType.TypeKind));
                                }
                            }

                            collectionWriter.WriteEnd();
                            collectionWriter.Flush();
                            break;
                        }

                        case EdmTypeKind.Complex:
                        {
                            Debug.Assert(model.GetClientTypeAnnotation(edmType).ElementType != null, "model.GetClientTypeAnnotation(edmType).ElementType != null");
                            ODataComplexValue complexValue = this.propertyConverter.CreateODataComplexValue(
                                model.GetClientTypeAnnotation(edmType).ElementType,
                                operationParameter.Value,
                                null /*propertyName*/,
                                false /*isCollectionItemType*/,
                                null /*visitedComplexTypeObjects*/);

                            Debug.Assert(complexValue != null, "complexValue != null");
                            parameterWriter.WriteValue(operationParameter.Name, complexValue);
                            break;
                        }

                        case EdmTypeKind.Primitive:
                            object primitiveValue = ODataPropertyConverter.ConvertPrimitiveValueToRecognizedODataType(operationParameter.Value, operationParameter.Value.GetType());
                            parameterWriter.WriteValue(operationParameter.Name, primitiveValue);
                            break;

                        case EdmTypeKind.Enum:
                            ODataEnumValue tmp = this.propertyConverter.CreateODataEnumValue(
                                model.GetClientTypeAnnotation(edmType).ElementType,
                                operationParameter.Value,
                                false);
                            parameterWriter.WriteValue(operationParameter.Name, tmp);

                            break;

                        default:
                            // EdmTypeKind.Entity
                            // EdmTypeKind.Row
                            // EdmTypeKind.EntityReference
                            throw new NotSupportedException(Strings.Serializer_InvalidParameterType(operationParameter.Name, edmType.TypeKind));
                        }
                    } // else
                }     // foreach

                parameterWriter.WriteEnd();
                parameterWriter.Flush();
            }
        }
Esempio n. 8
0
        private async Task WriteOperationParameterAsync(ODataParameterWriter parameterWriter, IEdmOperationParameter operationParameter, string paramName, object paramValue)
        {
            switch (operationParameter.Type.Definition.TypeKind)
            {
            case EdmTypeKind.Primitive:
            case EdmTypeKind.Complex:
                await parameterWriter.WriteValueAsync(paramName, paramValue);

                break;

            case EdmTypeKind.Enum:
                await parameterWriter.WriteValueAsync(paramName, new ODataEnumValue(paramValue.ToString()));

                break;

            case EdmTypeKind.Entity:
                var entryWriter = await parameterWriter.CreateEntryWriterAsync(paramName);

                var entry = CreateODataEntry(operationParameter.Type.Definition.FullTypeName(), paramValue.ToDictionary());
                await entryWriter.WriteStartAsync(entry);

                await entryWriter.WriteEndAsync();

                break;

            case EdmTypeKind.Collection:
                var collectionType = operationParameter.Type.Definition as IEdmCollectionType;
                var elementType    = collectionType.ElementType;
                if (elementType.Definition.TypeKind == EdmTypeKind.Entity)
                {
                    var feedWriter = await parameterWriter.CreateFeedWriterAsync(paramName);

                    var feed = new ODataFeed();
                    await feedWriter.WriteStartAsync(feed);

                    foreach (var item in paramValue as IEnumerable)
                    {
                        var feedEntry = CreateODataEntry(elementType.Definition.FullTypeName(), item.ToDictionary());

                        await feedWriter.WriteStartAsync(feedEntry);

                        await feedWriter.WriteEndAsync();
                    }
                    await feedWriter.WriteEndAsync();
                }
                else
                {
                    var collectionWriter = await parameterWriter.CreateCollectionWriterAsync(paramName);

                    await collectionWriter.WriteStartAsync(new ODataCollectionStart());

                    foreach (var item in paramValue as IEnumerable)
                    {
                        await collectionWriter.WriteItemAsync(item);
                    }
                    await collectionWriter.WriteEndAsync();
                }
                break;

            default:
                throw new NotSupportedException(string.Format("Unable to write action parameter of a type {0}", operationParameter.Type.Definition.TypeKind));
            }
        }