Beispiel #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MessageWriterSettingsArgs"/> class.
        /// </summary>
        /// <param name="settings">The settings.</param>
        public MessageWriterSettingsArgs(ODataMessageWriterSettings settings)
        {
            WebUtil.CheckArgumentNull(settings, "settings");

            this.Settings = settings;
        }
Beispiel #2
0
        internal void ExecuteQuery()
        {
            try
            {
                if (this.requestContentStream != null && this.requestContentStream.Stream != null)
                {
                    this.Request.SetRequestStream(this.requestContentStream);
                }
#if false
                if ((null != requestContent) && (0 < requestContent.Length))
                {
                    using (System.IO.Stream stream = Util.NullCheck(this.Request.GetRequestStream(), InternalError.InvalidGetRequestStream))
                    {
                        byte[] buffer       = requestContent.GetBuffer();
                        int    bufferOffset = checked ((int)requestContent.Position);
                        int    bufferLength = checked ((int)requestContent.Length) - bufferOffset;

                        // the following is useful in the debugging Immediate Window
                        // string x = System.Text.Encoding.UTF8.GetString(buffer, bufferOffset, bufferLength);
                        stream.Write(buffer, bufferOffset, bufferLength);
                    }
                }
#endif
                IODataResponseMessage response = null;
                response = this.RequestInfo.GetSyncronousResponse(this.Request, true);
                this.SetHttpWebResponse(Util.NullCheck(response, InternalError.InvalidGetResponse));

                if (HttpStatusCode.NoContent != this.StatusCode)
                {
                    using (Stream stream = this.responseMessage.GetStream())
                    {
                        if (null != stream)
                        {
                            Stream copy = this.GetAsyncResponseStreamCopy();
                            this.outputResponseStream = copy;

                            Byte[] buffer = this.GetAsyncResponseStreamCopyBuffer();

                            long copied = WebUtil.CopyStream(stream, copy, ref buffer);
                            if (this.responseStreamOwner)
                            {
                                if (0 == copied)
                                {
                                    this.outputResponseStream = null;
                                }
                                else if (copy.Position < copy.Length)
                                {   // In Silverlight, generally 3 bytes less than advertised by ContentLength are read
                                    ((MemoryStream)copy).SetLength(copy.Position);
                                }
                            }

                            this.PutAsyncResponseStreamCopyBuffer(buffer);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                this.HandleFailure(e);
                throw;
            }
            finally
            {
                this.SetCompleted();
                this.CompletedRequest();
            }

            if (null != this.Failure)
            {
                throw this.Failure;
            }
        }
Beispiel #3
0
        /// <summary>
        /// MethodCallExpression visit method
        /// </summary>
        /// <param name="m">The MethodCallExpression expression to visit</param>
        /// <returns>The visited MethodCallExpression expression </returns>
        internal override Expression VisitMethodCall(MethodCallExpression m)
        {
            string methodName;

            if (TypeSystem.TryGetQueryOptionMethod(m.Method, out methodName))
            {
                this.builder.Append(methodName);
                this.builder.Append(UriHelper.LEFTPAREN);

                // There is a single function, 'contains', which reorders its argument with
                // respect to the CLR method. Thus handling it as a special case rather than
                // using a more general argument reordering mechanism.
                if (methodName == "contains")
                {
                    Debug.Assert(m.Method.Name == "Contains", "m.Method.Name == 'Contains'");
                    Debug.Assert(m.Object != null, "m.Object != null");
                    Debug.Assert(m.Arguments.Count == 1, "m.Arguments.Count == 1");
                    this.Visit(m.Object);
                    this.builder.Append(UriHelper.COMMA);
                    this.Visit(m.Arguments[0]);
                }
                else
                {
                    if (m.Object != null)
                    {
                        this.Visit(m.Object);
                    }

                    if (m.Arguments.Count > 0)
                    {
                        if (m.Object != null)
                        {
                            this.builder.Append(UriHelper.COMMA);
                        }

                        for (int ii = 0; ii < m.Arguments.Count; ii++)
                        {
                            this.Visit(m.Arguments[ii]);
                            if (ii < m.Arguments.Count - 1)
                            {
                                this.builder.Append(UriHelper.COMMA);
                            }
                        }
                    }
                }

                this.builder.Append(UriHelper.RIGHTPAREN);
            }
            else if (m.Method.Name == "HasFlag")
            {
                Debug.Assert(m.Method.Name == "HasFlag", "m.Method.Name == 'HasFlag'");
                Debug.Assert(m.Object != null, "m.Object != null");
                Debug.Assert(m.Arguments.Count == 1, "m.Arguments.Count == 1");
                this.Visit(m.Object);
                this.builder.Append(UriHelper.SPACE);
                this.builder.Append(UriHelper.HAS);
                this.builder.Append(UriHelper.SPACE);
                this.Visit(m.Arguments[0]);
            }
            else
            {
                SequenceMethod sequenceMethod;
                if (ReflectionUtil.TryIdentifySequenceMethod(m.Method, out sequenceMethod))
                {
                    if (ReflectionUtil.IsAnyAllMethod(sequenceMethod))
                    {
                        // Raise the uriVersion each time we write any or all methods to the uri.
                        WebUtil.RaiseVersion(ref this.uriVersion, Util.ODataVersion4);

                        this.Visit(m.Arguments[0]);
                        this.builder.Append(UriHelper.FORWARDSLASH);
                        if (sequenceMethod == SequenceMethod.All)
                        {
                            this.builder.Append(XmlConstants.AllMethodName);
                        }
                        else
                        {
                            this.builder.Append(XmlConstants.AnyMethodName);
                        }

                        this.builder.Append(UriHelper.LEFTPAREN);
                        if (sequenceMethod != SequenceMethod.Any)
                        {
                            // SequenceMethod.Any represents Enumerable.Any(), which has only source argument
                            // AnyPredicate and All has a second parameter which is the predicate lambda.
                            Debug.Assert(m.Arguments.Count == 2, "m.Arguments.Count() == 2");
                            LambdaExpression le            = (LambdaExpression)m.Arguments[1];
                            string           rangeVariable = le.Parameters[0].Name;
                            this.builder.Append(rangeVariable);
                            this.builder.Append(UriHelper.COLON);
                            this.scopeCount++;
                            this.Visit(le.Body);
                            this.scopeCount--;
                        }

                        this.builder.Append(UriHelper.RIGHTPAREN);
                        return(m);
                    }
                    else if (sequenceMethod == SequenceMethod.OfType && this.parent != null)
                    {
                        // check to see if this is an OfType filter for Any or All.
                        // e.g. ctx.CreateQuery<Movie>("Movies").Where(m=>m.Actors.OfType<MegaStar>().Any())
                        //      which translates to /Movies()?$filter=Actors/MegaStar/any()
                        MethodCallExpression mce = this.parent as MethodCallExpression;
                        if (mce != null && ReflectionUtil.TryIdentifySequenceMethod(mce.Method, out sequenceMethod) && ReflectionUtil.IsAnyAllMethod(sequenceMethod))
                        {
                            Type filteredType = mce.Method.GetGenericArguments().SingleOrDefault();
                            if (ClientTypeUtil.TypeOrElementTypeIsEntity(filteredType))
                            {
                                this.Visit(m.Arguments[0]);
                                this.builder.Append(UriHelper.FORWARDSLASH);

                                UriHelper.AppendTypeSegment(this.builder, filteredType, this.context, this.inPath, ref this.uriVersion);

                                return(m);
                            }
                        }
                    }
                    else if (sequenceMethod == SequenceMethod.Count && this.parent != null)
                    {
                        if (m.Arguments.Any() && m.Arguments[0] != null)
                        {
                            this.Visit(m.Arguments[0]);
                        }

                        this.builder.Append(UriHelper.FORWARDSLASH).Append(UriHelper.DOLLARSIGN).Append(UriHelper.COUNT);
                        return(m);
                    }
                    else if (sequenceMethod == SequenceMethod.Contains)
                    {
                        // First argument is the collection expression
                        // Second argument is the value expression
                        // Note that arguments must be reordered for the IN operator
                        // e.g. ctx.CreateQuery<Product>("Products").Where(p => (new [] { "Milk", "Cheese", "Donut"}).Contains(p.Name))
                        //      which translates to /Products()?$filter=Name in ('Milk', 'Cheese', 'Donut')
                        this.Visit(m.Arguments[1]);
                        this.builder.Append(UriHelper.SPACE)
                        .Append(UriHelper.IN)
                        .Append(UriHelper.SPACE);
                        this.Visit(m.Arguments[0]);
                        return(m);
                    }
                }
                else
                {
                    if (m.Object != null)
                    {
                        this.Visit(m.Object);
                    }

                    if (m.Method.Name != "GetValue" && m.Method.Name != "GetValueAsync")
                    {
                        this.builder.Append(UriHelper.FORWARDSLASH);

                        // writing functions in query options
                        writingFunctionsInQuery = true;
                        string declaringType = this.context.ResolveNameFromTypeInternal(m.Method.DeclaringType);
                        if (string.IsNullOrEmpty(declaringType))
                        {
                            throw new NotSupportedException(Strings.ALinq_CantTranslateExpression(m.ToString()));
                        }

                        int    index            = declaringType.LastIndexOf('.');
                        string fullNamespace    = declaringType.Remove(index + 1);
                        string serverMethodName = ClientTypeUtil.GetServerDefinedName(m.Method);
                        this.builder.Append(fullNamespace + serverMethodName);
                        this.builder.Append(UriHelper.LEFTPAREN);
                        string[] argumentNames = m.Method.GetParameters().Select(p => p.Name).ToArray();
                        for (int i = 0; i < m.Arguments.Count; ++i)
                        {
                            this.builder.Append(argumentNames[i]);
                            this.builder.Append(UriHelper.EQUALSSIGN);
                            this.scopeCount++;
                            this.Visit(m.Arguments[i]);
                            this.scopeCount--;
                            this.builder.Append(UriHelper.COMMA);
                        }

                        if (m.Arguments.Any())
                        {
                            this.builder.Remove(this.builder.Length - 1, 1);
                        }

                        this.builder.Append(UriHelper.RIGHTPAREN);
                        writingFunctionsInQuery = false;
                    }

                    return(m);
                }

                this.cantTranslateExpression = true;
            }

            return(m);
        }
Beispiel #4
0
        private Exception ProcessCurrentOperationResponse(ODataBatchReader batchReader, bool isChangesetOperation)
        {
            Debug.Assert(batchReader != null, "batchReader != null");
            Debug.Assert(batchReader.State == ODataBatchReaderState.Operation, "This method requires the batch reader to be on an operation.");

            ODataBatchOperationResponseMessage operationResponseMessage = batchReader.CreateOperationResponseMessage();
            Descriptor descriptor = null;

            if (isChangesetOperation)
            {
                // We need to peek at the content-Id before handing the response to the user, so we can expose the Descriptor them.
                // We're OK with this exception to our general rule of not using them before ReceivingResponse event is fired.
                this.entryIndex = this.ValidateContentID(operationResponseMessage.ContentId);
                descriptor      = this.ChangedEntries[entryIndex];
            }

            // If we hit en error inside a batch, we will never expose a descriptor since we don't know which one to return.
            // The descriptor we fetched above based on the content-ID is bogus because the server returns an errounous content-id when
            // it hits an error inside batch.
            if (!WebUtil.SuccessStatusCode((HttpStatusCode)operationResponseMessage.StatusCode))
            {
                descriptor = null;
            }

            this.RequestInfo.Context.FireReceivingResponseEvent(new ReceivingResponseEventArgs(operationResponseMessage, descriptor, true));

            // We need to know if the content of the operation response is empty or not.
            // We also need to cache the entire content, since in case of GET response the response itself will be parsed
            // lazily and so it can happen that we will move the batch reader after this operation before we actually read
            // the content of the operation.
            Stream originalOperationResponseContentStream = operationResponseMessage.GetStream();

            if (originalOperationResponseContentStream == null)
            {
                Error.ThrowBatchExpectedResponse(InternalError.NullResponseStream);
            }

            MemoryStream operationResponseContentStream;

            try
            {
                operationResponseContentStream = new MemoryStream();
                WebUtil.CopyStream(originalOperationResponseContentStream, operationResponseContentStream, ref this.streamCopyBuffer);
                operationResponseContentStream.Position = 0;
            }
            finally
            {
                originalOperationResponseContentStream.Dispose();
            }

            this.currentOperationResponse = new CurrentOperationResponse(
                (HttpStatusCode)operationResponseMessage.StatusCode,
                operationResponseMessage.Headers,
                operationResponseContentStream);

            Version responseVersion;
            string  headerName = XmlConstants.HttpODataVersion;

            return(BaseSaveResult.HandleResponse(
                       this.RequestInfo,
                       this.currentOperationResponse.StatusCode,
                       this.currentOperationResponse.Headers.GetHeader(headerName),
                       () => this.currentOperationResponse.ContentStream,
                       false,
                       out responseVersion));
        }
Beispiel #5
0
 /// <summary>Releases all resources used by the current instance of the <see cref="T:Microsoft.OData.Client.DataServiceStreamResponse" /> class.</summary>
 public void Dispose()
 {
     WebUtil.DisposeMessage(this.responseMessage);
 }
Beispiel #6
0
 /// <summary>Raise the UriVersion if it is lower than <paramref name="newVersion"/>.</summary>
 /// <param name="newVersion">Uri version from the expand and projection paths</param>
 internal void RaiseUriVersion(Version newVersion)
 {
     Debug.Assert(newVersion != null, "newVersion != null");
     WebUtil.RaiseVersion(ref this.uriVersion, newVersion);
 }
        /// <summary>
        /// MethodCallExpression visit method
        /// </summary>
        /// <param name="m">The MethodCallExpression expression to visit</param>
        /// <returns>The visited MethodCallExpression expression </returns>
        internal override Expression VisitMethodCall(MethodCallExpression m)
        {
            string methodName;

            if (TypeSystem.TryGetQueryOptionMethod(m.Method, out methodName))
            {
                this.builder.Append(methodName);
                this.builder.Append(UriHelper.LEFTPAREN);

                // There is a single function, 'contains', which reorders its argument with
                // respect to the CLR method. Thus handling it as a special case rather than
                // using a more general argument reordering mechanism.
                if (methodName == "contains")
                {
                    Debug.Assert(m.Method.Name == "Contains", "m.Method.Name == 'Contains'");
                    Debug.Assert(m.Object != null, "m.Object != null");
                    Debug.Assert(m.Arguments.Count == 1, "m.Arguments.Count == 1");
                    this.Visit(m.Object);
                    this.builder.Append(UriHelper.COMMA);
                    this.Visit(m.Arguments[0]);
                }
                else
                {
                    if (m.Object != null)
                    {
                        this.Visit(m.Object);
                    }

                    if (m.Arguments.Count > 0)
                    {
                        if (m.Object != null)
                        {
                            this.builder.Append(UriHelper.COMMA);
                        }

                        for (int ii = 0; ii < m.Arguments.Count; ii++)
                        {
                            this.Visit(m.Arguments[ii]);
                            if (ii < m.Arguments.Count - 1)
                            {
                                this.builder.Append(UriHelper.COMMA);
                            }
                        }
                    }
                }

                this.builder.Append(UriHelper.RIGHTPAREN);
            }
            else if (m.Method.Name == "HasFlag")
            {
                Debug.Assert(m.Method.Name == "HasFlag", "m.Method.Name == 'HasFlag'");
                Debug.Assert(m.Object != null, "m.Object != null");
                Debug.Assert(m.Arguments.Count == 1, "m.Arguments.Count == 1");
                this.Visit(m.Object);
                this.builder.Append(UriHelper.SPACE);
                this.builder.Append(UriHelper.HAS);
                this.builder.Append(UriHelper.SPACE);
                this.Visit(m.Arguments[0]);
            }
            else
            {
                SequenceMethod sequenceMethod;
                if (ReflectionUtil.TryIdentifySequenceMethod(m.Method, out sequenceMethod))
                {
                    if (ReflectionUtil.IsAnyAllMethod(sequenceMethod))
                    {
                        // Raise the uriVersion each time we write any or all methods to the uri.
                        WebUtil.RaiseVersion(ref this.uriVersion, Util.ODataVersion4);

                        this.Visit(m.Arguments[0]);
                        this.builder.Append(UriHelper.FORWARDSLASH);
                        if (sequenceMethod == SequenceMethod.All)
                        {
                            this.builder.Append(XmlConstants.AllMethodName);
                        }
                        else
                        {
                            this.builder.Append(XmlConstants.AnyMethodName);
                        }

                        this.builder.Append(UriHelper.LEFTPAREN);
                        if (sequenceMethod != SequenceMethod.Any)
                        {
                            // SequenceMethod.Any represents Enumerable.Any(), which has only source argument
                            // AnyPredicate and All has a second parameter which is the predicate lambda.
                            Debug.Assert(m.Arguments.Count() == 2, "m.Arguments.Count() == 2");
                            LambdaExpression le            = (LambdaExpression)m.Arguments[1];
                            string           rangeVariable = le.Parameters[0].Name;
                            this.builder.Append(rangeVariable);
                            this.builder.Append(UriHelper.COLON);
                            this.scopeCount++;
                            this.Visit(le.Body);
                            this.scopeCount--;
                        }

                        this.builder.Append(UriHelper.RIGHTPAREN);
                        return(m);
                    }
                    else if (sequenceMethod == SequenceMethod.OfType && this.parent != null)
                    {
                        // check to see if this is an OfType filter for Any or All.
                        // e.g. ctx.CreateQuery<Movie>("Movies").Where(m=>m.Actors.OfType<MegaStar>().Any())
                        //      which translates to /Movies()?$filter=Actors/MegaStar/any()
                        MethodCallExpression mce = this.parent as MethodCallExpression;
                        if (mce != null &&
                            ReflectionUtil.TryIdentifySequenceMethod(mce.Method, out sequenceMethod) &&
                            ReflectionUtil.IsAnyAllMethod(sequenceMethod))
                        {
                            Type filteredType = mce.Method.GetGenericArguments().SingleOrDefault();
                            if (ClientTypeUtil.TypeOrElementTypeIsEntity(filteredType))
                            {
                                this.Visit(m.Arguments[0]);
                                this.builder.Append(UriHelper.FORWARDSLASH);

                                UriHelper.AppendTypeSegment(this.builder, filteredType, this.context, this.inPath, ref this.uriVersion);

                                return(m);
                            }
                        }
                    }
                }

                this.cantTranslateExpression = true;
            }

            return(m);
        }
Beispiel #8
0
        /// <summary>
        /// Creates and returns an ODataCollectionValue from the given value.
        /// </summary>
        /// <param name="collectionItemType">The type of the value.</param>
        /// <param name="propertyName">If the value is a property, then it represents the name of the property. Can be null, for non-property.</param>
        /// <param name="value">The value.</param>
        /// <param name="visitedComplexTypeObjects">Set of instances of complex types encountered in the hierarchy. Used to detect cycles.</param>
        /// <param name="isDynamicProperty">Whether this collection property is a dynamic property</param>
        /// <param name="setTypeAnnotation">If true, set the type annotation on ODataValue.</param>
        /// <returns>An ODataCollectionValue representing the given value.</returns>
        internal ODataCollectionValue CreateODataCollection(Type collectionItemType, string propertyName, object value, HashSet <object> visitedComplexTypeObjects, bool isDynamicProperty, bool setTypeAnnotation = true)
        {
            Debug.Assert(collectionItemType != null, "collectionItemType != null");

            WebUtil.ValidateCollection(collectionItemType, value, propertyName, isDynamicProperty);

            PrimitiveType ptype;
            bool          isCollectionOfPrimitiveTypes = PrimitiveType.TryGetPrimitiveType(collectionItemType, out ptype);

            ODataCollectionValue collection = new ODataCollectionValue();
            IEnumerable          enumerablePropertyValue = (IEnumerable)value;
            string collectionItemTypeName;
            string collectionTypeName;

            if (isCollectionOfPrimitiveTypes)
            {
                collectionItemTypeName = ClientConvert.GetEdmType(Nullable.GetUnderlyingType(collectionItemType) ?? collectionItemType);

                if (enumerablePropertyValue != null)
                {
                    collection.Items = Util.GetEnumerable(
                        enumerablePropertyValue,
                        (val) =>
                    {
                        if (val == null)
                        {
                            return(null);
                        }

                        WebUtil.ValidatePrimitiveCollectionItem(val, propertyName, collectionItemType);
                        return(ConvertPrimitiveValueToRecognizedODataType(val, collectionItemType));
                    });
                }

                // TypeName for primitives should be the EDM name since that's what we will be able to look up in the model
                collectionTypeName = collectionItemTypeName;
            }
            else
            {
                Type collectionItemTypeTmp = Nullable.GetUnderlyingType(collectionItemType) ?? collectionItemType;

                // Note that the collectionItemTypeName will be null if the context does not have the ResolveName func.
                collectionItemTypeName = this.requestInfo.ResolveNameFromType(collectionItemType);

                if (enumerablePropertyValue != null)
                {
                    collection.Items = Util.GetEnumerable(
                        enumerablePropertyValue,
                        (val) =>
                    {
                        if (val == null)
                        {
                            return(new ODataEnumValue(null, collectionItemType.FullName) as ODataValue);
                        }

                        return(new ODataEnumValue(ClientTypeUtil.GetEnumValuesString(val.ToString(), collectionItemTypeTmp), collectionItemType.FullName) as ODataValue);
                    });
                }

                // TypeName for complex types needs to be the client type name (not the one we resolved above) since it will be looked up in the client model
                collectionTypeName = collectionItemType.FullName;
            }

            // Set the type name to use for client type lookups and validation.
            collection.TypeName = GetCollectionName(collectionTypeName);

            // Ideally, we should not set type annotation on collection value.
            // To keep backward compatibility, we'll keep it in request body, but do not include it in url.
            if (setTypeAnnotation)
            {
                string wireTypeName = GetCollectionName(collectionItemTypeName);
                collection.TypeAnnotation = new ODataTypeAnnotation(wireTypeName);
            }

            return(collection);
        }
        /// <summary>
        /// Creates and returns an ODataCollectionValue from the given value.
        /// </summary>
        /// <param name="collectionItemType">The type of the value.</param>
        /// <param name="propertyName">If the value is a property, then it represents the name of the property. Can be null, for non-property.</param>
        /// <param name="value">The value.</param>
        /// <param name="visitedComplexTypeObjects">Set of instances of complex types encountered in the hierarchy. Used to detect cycles.</param>
        /// <param name="isDynamicProperty">Whether this collection property is a dynamic property</param>
        /// <returns>An ODataCollectionValue representing the given value.</returns>
        internal ODataCollectionValue CreateODataCollection(Type collectionItemType, string propertyName, object value, HashSet <object> visitedComplexTypeObjects, bool isDynamicProperty)
        {
            Debug.Assert(collectionItemType != null, "collectionItemType != null");

            WebUtil.ValidateCollection(collectionItemType, value, propertyName, isDynamicProperty);

            PrimitiveType ptype;
            bool          isCollectionOfPrimitiveTypes = PrimitiveType.TryGetPrimitiveType(collectionItemType, out ptype);

            ODataCollectionValue collection = new ODataCollectionValue();
            IEnumerable          enumerablePropertyValue = (IEnumerable)value;
            string collectionItemTypeName;
            string collectionTypeName;

            if (isCollectionOfPrimitiveTypes)
            {
                collectionItemTypeName = ClientConvert.GetEdmType(Nullable.GetUnderlyingType(collectionItemType) ?? collectionItemType);

                if (enumerablePropertyValue != null)
                {
                    collection.Items = Util.GetEnumerable(
                        enumerablePropertyValue,
                        (val) =>
                    {
                        WebUtil.ValidateCollectionItem(val);
                        WebUtil.ValidatePrimitiveCollectionItem(val, propertyName, collectionItemType);
                        return(ConvertPrimitiveValueToRecognizedODataType(val, collectionItemType));
                    });
                }

                // TypeName for primitives should be the EDM name since that's what we will be able to look up in the model
                collectionTypeName = collectionItemTypeName;
            }
            else
            {
                Type collectionItemTypeTmp = Nullable.GetUnderlyingType(collectionItemType) ?? collectionItemType;
                bool areEnumItems          = collectionItemTypeTmp.IsEnum();

                // Note that the collectionItemTypeName will be null if the context does not have the ResolveName func.
                collectionItemTypeName = this.requestInfo.ResolveNameFromType(collectionItemType);

                if (enumerablePropertyValue != null)
                {
                    collection.Items = Util.GetEnumerable(
                        enumerablePropertyValue,
                        (val) =>
                    {
                        if (areEnumItems)
                        {
                            if (val == null)
                            {
                                return(new ODataEnumValue(null, collectionItemType.FullName) as ODataValue);
                            }

                            return(new ODataEnumValue(ClientTypeUtil.GetEnumValuesString(val.ToString(), collectionItemTypeTmp), collectionItemType.FullName) as ODataValue);
                        }
                        else
                        {
                            WebUtil.ValidateCollectionItem(val);
                            WebUtil.ValidateComplexCollectionItem(val, propertyName, collectionItemType);
                            return(this.CreateODataComplexValue(collectionItemType, val, propertyName, true /*isCollectionItem*/, visitedComplexTypeObjects)
                                   as ODataValue);
                        }
                    });
                }

                // TypeName for complex types needs to be the client type name (not the one we resolved above) since it will be looked up in the client model
                collectionTypeName = collectionItemType.FullName;
            }

            // Set the type name to use for client type lookups and validation. Because setting this value can cause validation to occur, we will
            // only do it for JSON Light, in order to avoid breaking changes with the WCF Data Services 5.0 release, since it was already shipped without this.
            if (!this.requestInfo.Format.UsingAtom)
            {
                collection.TypeName = GetCollectionName(collectionTypeName);
            }

            string wireTypeName = GetCollectionName(collectionItemTypeName);

            collection.SetAnnotation(new SerializationTypeNameAnnotation {
                TypeName = wireTypeName
            });
            return(collection);
        }