/// <summary> /// Remove the Edm. prefix from the type name if it is primitive type. /// </summary> /// <param name="typeName">The type name to remove the Edm. prefix</param> /// <returns>The type name without the Edm. Prefix</returns> internal static string RemoveEdmPrefixFromTypeName(string typeName) { if (!string.IsNullOrEmpty(typeName)) { string itemTypeName = EdmLibraryExtensions.GetCollectionItemTypeName(typeName); if (itemTypeName == null) { IEdmSchemaType primitiveType = EdmLibraryExtensions.ResolvePrimitiveTypeName(typeName); if (primitiveType != null) { return(primitiveType.ShortQualifiedName()); } } else { IEdmSchemaType primitiveType = EdmLibraryExtensions.ResolvePrimitiveTypeName(itemTypeName); if (primitiveType != null) { return(EdmLibraryExtensions.GetCollectionTypeName(primitiveType.ShortQualifiedName())); } } } return(typeName); }
/// <summary> /// Prepare the type name for writing. /// 1) If it is primitive type, remove the Edm. prefix. /// 2) If it is a non-primitive type or 4.0, prefix with #. /// </summary> /// <param name="typeName">The type name to write</param> /// <param name="version">OData Version of payload being written</param> /// <returns>The type name for writing</returns> internal static string PrefixTypeNameForWriting(string typeName, ODataVersion version) { if (!string.IsNullOrEmpty(typeName)) { string itemTypeName = EdmLibraryExtensions.GetCollectionItemTypeName(typeName); if (itemTypeName == null) { IEdmSchemaType primitiveType = EdmLibraryExtensions.ResolvePrimitiveTypeName(typeName); if (primitiveType != null) { typeName = primitiveType.ShortQualifiedName(); return(version < ODataVersion.V401 ? PrefixTypeName(typeName) : typeName); } } else { IEdmSchemaType primitiveType = EdmLibraryExtensions.ResolvePrimitiveTypeName(itemTypeName); if (primitiveType != null) { typeName = EdmLibraryExtensions.GetCollectionTypeName(primitiveType.ShortQualifiedName()); return(version < ODataVersion.V401 ? PrefixTypeName(typeName) : typeName); } } } return(PrefixTypeName(typeName)); }
/// <summary> /// Add the Edm. prefix to the primitive type if there isn't. /// </summary> /// <param name="typeName">The type name which may be not prefixed (Edm.).</param> /// <returns>The type name with Edm. prefix</returns> internal static string AddEdmPrefixOfTypeName(string typeName) { if (!string.IsNullOrEmpty(typeName)) { string itemTypeName = EdmLibraryExtensions.GetCollectionItemTypeName(typeName); if (itemTypeName == null) { // This is the primitive type IEdmSchemaType primitiveType = EdmLibraryExtensions.ResolvePrimitiveTypeName(typeName); if (primitiveType != null) { return(primitiveType.FullName()); } } else { // This is the collection type IEdmSchemaType primitiveType = EdmLibraryExtensions.ResolvePrimitiveTypeName(itemTypeName); if (primitiveType != null) { return(EdmLibraryExtensions.GetCollectionTypeName(primitiveType.FullName())); } } } // Return the origin type name return(typeName); }
internal static IEdmType ResolveTypeName( IEdmModel model, IEdmType expectedType, string typeName, Func <IEdmType, string, IEdmType> customTypeResolver, ODataVersion version, out EdmTypeKind typeKind) { Debug.Assert(model != null, "model != null"); Debug.Assert(typeName != null, "typeName != null"); IEdmType resolvedType = null; // Collection types should only be recognized in V3 and higher. string itemTypeName = EdmLibraryExtensions.GetCollectionItemTypeName(typeName); if (itemTypeName == null) { // Note: we require the type resolver or the model to also resolve // primitive types. if (customTypeResolver != null && model.IsUserModel()) { resolvedType = customTypeResolver(expectedType, typeName); if (resolvedType == null) { // If a type resolver is specified it must never return null. throw new ODataException(Strings.MetadataUtils_ResolveTypeName(typeName)); } } else { resolvedType = model.FindType(typeName); } typeKind = resolvedType == null ? EdmTypeKind.None : resolvedType.TypeKind; } else { // Collection typeKind = EdmTypeKind.Collection; EdmTypeKind itemTypeKind; IEdmType expectedItemType = null; if (customTypeResolver != null && expectedType != null && expectedType.TypeKind == EdmTypeKind.Collection) { expectedItemType = ((IEdmCollectionType)expectedType).ElementType.Definition; } IEdmType itemType = ResolveTypeName(model, expectedItemType, itemTypeName, customTypeResolver, version, out itemTypeKind); if (itemType != null) { resolvedType = EdmLibraryExtensions.GetCollectionType(itemType); } } return(resolvedType); }
internal static string ValidateCollectionTypeName(string collectionTypeName) { string collectionItemTypeName = EdmLibraryExtensions.GetCollectionItemTypeName(collectionTypeName); if (collectionItemTypeName == null) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_InvalidCollectionTypeName(collectionTypeName)); } return(collectionItemTypeName); }
/// <summary> /// Validates that <paramref name="collectionTypeName"/> is a valid type name for a collection and returns its item type name. /// </summary> /// <param name="collectionTypeName">The name of the collection type.</param> /// <returns>The item type name for the <paramref name="collectionTypeName"/>.</returns> internal static string ValidateCollectionTypeName(string collectionTypeName) { DebugUtils.CheckNoExternalCallers(); string itemTypeName = EdmLibraryExtensions.GetCollectionItemTypeName(collectionTypeName); if (itemTypeName == null) { throw new ODataException(Strings.ValidationUtils_InvalidCollectionTypeName(collectionTypeName)); } return(itemTypeName); }
/// <summary> /// Resolves a type. /// </summary> /// <param name="typeName">The type name.</param> /// <param name="readerBehavior">Reader behavior if the caller is a reader, null if no reader behavior is available.</param> /// <param name="version">The version of the payload being read.</param> /// <returns>The resolved Edm type.</returns> private IEdmType ResolveType(string typeName, ODataReaderBehavior readerBehavior, ODataVersion version) { string typeNameToResolve = EdmLibraryExtensions.GetCollectionItemTypeName(typeName) ?? typeName; EdmTypeKind typeKind; IEdmType resolvedType = MetadataUtils.ResolveTypeNameForRead(this.model, /*expectedType*/ null, typeNameToResolve, readerBehavior, version, out typeKind); if (resolvedType == null || resolvedType.TypeKind != EdmTypeKind.Primitive && resolvedType.TypeKind != EdmTypeKind.Complex) { throw new ODataException(ODataErrorStrings.ODataJsonLightMetadataUriParser_InvalidEntitySetNameOrTypeName(UriUtilsCommon.UriToString(this.parseResult.MetadataUri), typeName)); } resolvedType = typeNameToResolve == typeName ? resolvedType : EdmLibraryExtensions.GetCollectionType(resolvedType.ToTypeReference(true /*nullable*/)); return(resolvedType); }
/// <summary> /// Resolves a type. /// </summary> /// <param name="typeName">The type name.</param> /// <param name="clientCustomTypeResolver">The function of client cuetom type resolver.</param> /// <param name="throwIfMetadataConflict">Whether to throw if a type specified in the ContextUri is not found in metadata.</param> /// <returns>The resolved Edm type.</returns> private ODataPayloadKind ResolveType(string typeName, Func <IEdmType, string, IEdmType> clientCustomTypeResolver, bool throwIfMetadataConflict) { string typeNameToResolve = EdmLibraryExtensions.GetCollectionItemTypeName(typeName) ?? typeName; bool isCollection = typeNameToResolve != typeName; EdmTypeKind typeKind; IEdmType resolvedType = MetadataUtils.ResolveTypeNameForRead(this.model, /*expectedType*/ null, typeNameToResolve, clientCustomTypeResolver, out typeKind); if (resolvedType == null && !throwIfMetadataConflict) { string namespaceName; string name; TypeUtils.ParseQualifiedTypeName(typeName, out namespaceName, out name, out isCollection); resolvedType = new EdmUntypedStructuredType(namespaceName, name); } if (resolvedType == null || resolvedType.TypeKind != EdmTypeKind.Primitive && resolvedType.TypeKind != EdmTypeKind.Enum && resolvedType.TypeKind != EdmTypeKind.Complex && resolvedType.TypeKind != EdmTypeKind.Entity && resolvedType.TypeKind != EdmTypeKind.TypeDefinition && resolvedType.TypeKind != EdmTypeKind.Untyped) { throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidEntitySetNameOrTypeName(UriUtils.UriToString(this.parseResult.ContextUri), typeName)); } if (resolvedType.TypeKind == EdmTypeKind.Entity || resolvedType.TypeKind == EdmTypeKind.Complex) { this.parseResult.EdmType = resolvedType; return(isCollection ? ODataPayloadKind.ResourceSet : ODataPayloadKind.Resource); } // For structured collection ,the EdmType is element type. for primitive collection, it is collection type resolvedType = isCollection ? EdmLibraryExtensions.GetCollectionType(resolvedType.ToTypeReference(true /*nullable*/)) : resolvedType; this.parseResult.EdmType = resolvedType; return(isCollection ? ODataPayloadKind.Collection : ODataPayloadKind.Property); }
/// <summary> /// Resolves a type. /// </summary> /// <param name="typeName">The type name.</param> /// <param name="readerBehavior">Reader behavior if the caller is a reader, null if no reader behavior is available.</param> /// <returns>The resolved Edm type.</returns> private ODataPayloadKind ResolveType(string typeName, ODataReaderBehavior readerBehavior) { string typeNameToResolve = EdmLibraryExtensions.GetCollectionItemTypeName(typeName) ?? typeName; bool isCollection = typeNameToResolve != typeName; EdmTypeKind typeKind; IEdmType resolvedType = MetadataUtils.ResolveTypeNameForRead(this.model, /*expectedType*/ null, typeNameToResolve, readerBehavior, out typeKind); if (resolvedType == null || resolvedType.TypeKind != EdmTypeKind.Primitive && resolvedType.TypeKind != EdmTypeKind.Enum && resolvedType.TypeKind != EdmTypeKind.Complex && resolvedType.TypeKind != EdmTypeKind.Entity && resolvedType.TypeKind != EdmTypeKind.TypeDefinition) { throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidEntitySetNameOrTypeName(UriUtils.UriToString(this.parseResult.ContextUri), typeName)); } if (resolvedType.TypeKind == EdmTypeKind.Entity) { this.parseResult.EdmType = resolvedType; return(isCollection ? ODataPayloadKind.Feed : ODataPayloadKind.Entry); } resolvedType = isCollection ? EdmLibraryExtensions.GetCollectionType(resolvedType.ToTypeReference(true /*nullable*/)) : resolvedType; this.parseResult.EdmType = resolvedType; return(isCollection ? ODataPayloadKind.Collection : ODataPayloadKind.Property); }
/// <summary> /// Read a collection from the reader. /// </summary> /// <param name="collectionTypeReference">The type of the collection to read (or null if no type is available).</param> /// <param name="payloadTypeName">The name of the collection type specified in the payload.</param> /// <param name="serializationTypeNameAnnotation">The serialization type name for the collection value (possibly null).</param> /// <returns>The value read from the payload.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element - the element to read the value for. /// XmlNodeType.Attribute - an attribute on the element to read the value for. /// Post-Condition: XmlNodeType.Element - the element was empty. /// XmlNodeType.EndElement - the element had some value. /// /// Note that this method will not read null values, those should be handled by the caller already. /// </remarks> private ODataCollectionValue ReadCollectionValue( IEdmCollectionTypeReference collectionTypeReference, string payloadTypeName, SerializationTypeNameAnnotation serializationTypeNameAnnotation) { this.AssertXmlCondition(XmlNodeType.Element, XmlNodeType.Attribute); Debug.Assert( collectionTypeReference == null || collectionTypeReference.IsNonEntityODataCollectionTypeKind(), "If the metadata is specified it must denote a collection for this method to work."); this.IncreaseRecursionDepth(); ODataCollectionValue collectionValue = new ODataCollectionValue(); // If we have a metadata type for the collection, use that type name // otherwise use the type name from the payload (if there was any). collectionValue.TypeName = collectionTypeReference == null ? payloadTypeName : collectionTypeReference.ODataFullName(); if (serializationTypeNameAnnotation != null) { collectionValue.SetAnnotation(serializationTypeNameAnnotation); } // Move to the element (so that if we were on an attribute we can test the element for being empty) this.XmlReader.MoveToElement(); List <object> items = new List <object>(); // Empty collections are valid - they have no items if (!this.XmlReader.IsEmptyElement) { // Read over the collection element to its first child node (or end-element) this.XmlReader.ReadStartElement(); IEdmTypeReference itemTypeReference = collectionTypeReference == null ? null : collectionTypeReference.ElementType(); DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker(); CollectionWithoutExpectedTypeValidator collectionValidator = null; if (collectionTypeReference == null) { // Parse the type name from the payload (if any), extract the item type name and construct a collection validator string itemTypeName = payloadTypeName == null ? null : EdmLibraryExtensions.GetCollectionItemTypeName(payloadTypeName); collectionValidator = new CollectionWithoutExpectedTypeValidator(itemTypeName); } do { switch (this.XmlReader.NodeType) { case XmlNodeType.Element: if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace)) { if (!this.XmlReader.LocalNameEquals(this.ODataCollectionItemElementName)) { throw new ODataException(o.Strings.ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement(this.XmlReader.LocalName, this.XmlReader.ODataNamespace)); } // We don't support EPM for collections so it is fine to say that EPM is not present object itemValue = this.ReadNonEntityValueImplementation( itemTypeReference, duplicatePropertyNamesChecker, collectionValidator, /*validateNullValue*/ true, /*epmPresent*/ false); // read over the end tag of the element or the start tag if the element was empty. this.XmlReader.Read(); // Validate the item (for example that it's not null) ValidationUtils.ValidateCollectionItem(itemValue, false /* isStreamable */); // Note that the ReadNonEntityValue already validated that the actual type of the value matches // the expected type (the itemType). items.Add(itemValue); } else { this.XmlReader.Skip(); } break; case XmlNodeType.EndElement: // End of the collection. break; default: // Non-element so for example a text node, just ignore this.XmlReader.Skip(); break; } }while (this.XmlReader.NodeType != XmlNodeType.EndElement); } collectionValue.Items = new ReadOnlyEnumerable(items); this.AssertXmlCondition(true, XmlNodeType.EndElement); Debug.Assert(collectionValue != null, "The method should never return null since it doesn't handle null values."); this.DecreaseRecursionDepth(); return(collectionValue); }
/// <summary> /// Reads the start of a collection; this includes collection-level properties (e.g., the 'results' property) if the version permits it. /// </summary> /// <param name="collectionStartPropertyAndAnnotationCollector">The duplicate property names checker used to keep track of the properties and annotations /// in the collection wrapper object.</param> /// <param name="isReadingNestedPayload">true if we are reading a nested collection inside a paramter payload; otherwise false.</param> /// <param name="expectedItemTypeReference">The expected item type reference or null if none is expected.</param> /// <param name="actualItemTypeReference">The validated actual item type reference (if specified in the payload) or the expected item type reference.</param> /// <returns>An <see cref="ODataCollectionStart"/> representing the collection-level information. Currently this is only the name of the collection in ATOM.</returns> /// <remarks> /// Pre-Condition: Any: the start of a nested collection value; if this is not a 'StartArray' node this method will fail. /// JsonNodeType.Property: the first property of the collection wrapper object after the context URI. /// JsonNodeType.EndObject: when the collection wrapper object has no properties (other than the context URI). /// Post-Condition: JsonNodeType.StartArray: the start of the array of the collection items. /// </remarks> internal ODataCollectionStart ReadCollectionStart( PropertyAndAnnotationCollector collectionStartPropertyAndAnnotationCollector, bool isReadingNestedPayload, IEdmTypeReference expectedItemTypeReference, out IEdmTypeReference actualItemTypeReference) { this.JsonReader.AssertNotBuffering(); actualItemTypeReference = expectedItemTypeReference; ODataCollectionStart collectionStart = null; if (isReadingNestedPayload) { Debug.Assert(!this.JsonLightInputContext.ReadingResponse, "Nested collections are only supported in parameter payloads in requests."); collectionStart = new ODataCollectionStart { Name = null }; } else { while (this.JsonReader.NodeType == JsonNodeType.Property) { IEdmTypeReference actualItemTypeRef = expectedItemTypeReference; this.ProcessProperty( collectionStartPropertyAndAnnotationCollector, this.ReadTypePropertyAnnotationValue, (propertyParsingResult, propertyName) => { switch (propertyParsingResult) { case PropertyParsingResult.ODataInstanceAnnotation: if (!IsValidODataAnnotationOfCollection(propertyName)) { throw new ODataException(ODataErrorStrings.ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties(propertyName)); } this.JsonReader.SkipValue(); break; case PropertyParsingResult.CustomInstanceAnnotation: this.JsonReader.SkipValue(); break; case PropertyParsingResult.PropertyWithoutValue: throw new ODataException(ODataErrorStrings.ODataJsonLightPropertyAndValueDeserializer_TopLevelPropertyAnnotationWithoutProperty(propertyName)); case PropertyParsingResult.PropertyWithValue: if (string.CompareOrdinal(JsonLightConstants.ODataValuePropertyName, propertyName) != 0) { throw new ODataException( ODataErrorStrings.ODataJsonLightPropertyAndValueDeserializer_InvalidTopLevelPropertyName(propertyName, JsonLightConstants.ODataValuePropertyName)); } string payloadTypeName = ValidateDataPropertyTypeNameAnnotation(collectionStartPropertyAndAnnotationCollector, propertyName); if (payloadTypeName != null) { string itemTypeName = EdmLibraryExtensions.GetCollectionItemTypeName(payloadTypeName); if (itemTypeName == null) { throw new ODataException(ODataErrorStrings.ODataJsonLightCollectionDeserializer_InvalidCollectionTypeName(payloadTypeName)); } EdmTypeKind targetTypeKind; ODataTypeAnnotation typeAnnotation; Func <EdmTypeKind> typeKindFromPayloadFunc = () => { throw new ODataException(ODataErrorStrings.General_InternalError(InternalErrorCodes.ODataJsonLightCollectionDeserializer_ReadCollectionStart_TypeKindFromPayloadFunc)); }; actualItemTypeRef = this.ReaderValidator.ResolvePayloadTypeNameAndComputeTargetType( EdmTypeKind.None, /*expectStructuredType*/ null, /*defaultPrimitivePayloadType*/ null, expectedItemTypeReference, itemTypeName, this.Model, typeKindFromPayloadFunc, out targetTypeKind, out typeAnnotation); } collectionStart = new ODataCollectionStart { Name = null }; break; case PropertyParsingResult.EndOfObject: break; case PropertyParsingResult.MetadataReferenceProperty: throw new ODataException(ODataErrorStrings.ODataJsonLightPropertyAndValueDeserializer_UnexpectedMetadataReferenceProperty(propertyName)); default: throw new ODataException(ODataErrorStrings.General_InternalError(InternalErrorCodes.ODataJsonLightCollectionDeserializer_ReadCollectionStart)); } }); actualItemTypeReference = actualItemTypeRef; } if (collectionStart == null) { // No collection property found; there should be exactly one property in the collection wrapper that does not have a reserved name. throw new ODataException(ODataErrorStrings.ODataJsonLightCollectionDeserializer_ExpectedCollectionPropertyNotFound(JsonLightConstants.ODataValuePropertyName)); } } // at this point the reader is positioned on the start array node for the collection contents if (this.JsonReader.NodeType != JsonNodeType.StartArray) { throw new ODataException(ODataErrorStrings.ODataJsonLightCollectionDeserializer_CannotReadCollectionContentStart(this.JsonReader.NodeType)); } this.JsonReader.AssertNotBuffering(); return(collectionStart); }
/// <summary> /// Read a collection from the reader. /// </summary> /// <param name="collectionTypeReference">The type of the collection to read (or null if no type is available).</param> /// <param name="payloadTypeName">The name of the collection type specified in the payload.</param> /// <param name="serializationTypeNameAnnotation">The serialization type name for the collection value (possibly null).</param> /// <returns>The value read from the payload.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element - the element to read the value for. /// XmlNodeType.Attribute - an attribute on the element to read the value for. /// Post-Condition: XmlNodeType.Element - the element was empty. /// XmlNodeType.EndElement - the element had some value. /// /// Note that this method will not read null values, those should be handled by the caller already. /// </remarks> private ODataCollectionValue ReadCollectionValue( IEdmCollectionTypeReference collectionTypeReference, string payloadTypeName, SerializationTypeNameAnnotation serializationTypeNameAnnotation) { this.AssertXmlCondition(XmlNodeType.Element, XmlNodeType.Attribute); Debug.Assert( collectionTypeReference == null || collectionTypeReference.IsNonEntityCollectionType(), "If the metadata is specified it must denote a collection for this method to work."); this.IncreaseRecursionDepth(); ODataCollectionValue collectionValue = new ODataCollectionValue(); // If we have a metadata type for the collection, use that type name // otherwise use the type name from the payload (if there was any). collectionValue.TypeName = collectionTypeReference == null ? payloadTypeName : collectionTypeReference.FullName(); if (serializationTypeNameAnnotation != null) { collectionValue.SetAnnotation(serializationTypeNameAnnotation); } // Move to the element (so that if we were on an attribute we can test the element for being empty) this.XmlReader.MoveToElement(); List <object> items = new List <object>(); // Empty collections are valid - they have no items if (!this.XmlReader.IsEmptyElement) { // Read over the collection element to its first child node (or end-element) this.XmlReader.ReadStartElement(); // If we don't have metadata (that is collectionType is null) we parse the type name // and extract the item type name from it. Then we create a CollectionWithoutExpectedTypeValidator // instance and use it to ensure that all item types read for the collection value are consistent with // the item type derived from the collection value's type name. // Note that if an item does not specify a type name but the collection value does, the item will be // assigned the item type name computed from the collection value's type. // Note that JSON doesn't have this problem since in JSON we always have metadata and thus the collectionType // is never null by the time we get to a similar place in the code. IEdmTypeReference itemTypeReference = collectionTypeReference == null ? null : collectionTypeReference.ElementType(); DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker(); CollectionWithoutExpectedTypeValidator collectionValidator = null; if (collectionTypeReference == null) { // Parse the type name from the payload (if any), extract the item type name and construct a collection validator string itemTypeName = payloadTypeName == null ? null : EdmLibraryExtensions.GetCollectionItemTypeName(payloadTypeName); collectionValidator = new CollectionWithoutExpectedTypeValidator(itemTypeName); } do { switch (this.XmlReader.NodeType) { case XmlNodeType.Element: if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataMetadataNamespace)) { if (!this.XmlReader.LocalNameEquals(this.ODataCollectionItemElementName)) { this.XmlReader.Skip(); } else { object itemValue = this.ReadNonEntityValueImplementation( itemTypeReference, duplicatePropertyNamesChecker, collectionValidator, /*validateNullValue*/ true, /*propertyName*/ null); // read over the end tag of the element or the start tag if the element was empty. this.XmlReader.Read(); // Validate the item (for example that it's not null) ValidationUtils.ValidateCollectionItem(itemValue, itemTypeReference.IsNullable()); // Note that the ReadNonEntityValue already validated that the actual type of the value matches // the expected type (the itemType). items.Add(itemValue); } } else if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace)) { throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement(this.XmlReader.LocalName, this.XmlReader.ODataMetadataNamespace)); } else { this.XmlReader.Skip(); } break; case XmlNodeType.EndElement: // End of the collection. break; default: // Non-element so for example a text node, just ignore this.XmlReader.Skip(); break; } }while (this.XmlReader.NodeType != XmlNodeType.EndElement); } collectionValue.Items = new ReadOnlyEnumerable(items); this.AssertXmlCondition(true, XmlNodeType.EndElement); Debug.Assert(collectionValue != null, "The method should never return null since it doesn't handle null values."); this.DecreaseRecursionDepth(); return(collectionValue); }
private ODataCollectionValue ReadCollectionValue(IEdmCollectionTypeReference collectionTypeReference, string payloadTypeName, SerializationTypeNameAnnotation serializationTypeNameAnnotation) { this.IncreaseRecursionDepth(); ODataCollectionValue value2 = new ODataCollectionValue { TypeName = (collectionTypeReference == null) ? payloadTypeName : collectionTypeReference.ODataFullName() }; if (serializationTypeNameAnnotation != null) { value2.SetAnnotation <SerializationTypeNameAnnotation>(serializationTypeNameAnnotation); } base.XmlReader.MoveToElement(); List <object> sourceEnumerable = new List <object>(); if (!base.XmlReader.IsEmptyElement) { base.XmlReader.ReadStartElement(); IEdmTypeReference expectedTypeReference = (collectionTypeReference == null) ? null : collectionTypeReference.ElementType(); DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = base.CreateDuplicatePropertyNamesChecker(); CollectionWithoutExpectedTypeValidator collectionValidator = null; if (collectionTypeReference == null) { string itemTypeNameFromCollection = (payloadTypeName == null) ? null : EdmLibraryExtensions.GetCollectionItemTypeName(payloadTypeName); collectionValidator = new CollectionWithoutExpectedTypeValidator(itemTypeNameFromCollection); } do { switch (base.XmlReader.NodeType) { case XmlNodeType.Element: if (base.XmlReader.NamespaceEquals(base.XmlReader.ODataNamespace)) { if (!base.XmlReader.LocalNameEquals(this.ODataCollectionItemElementName)) { throw new ODataException(Microsoft.Data.OData.Strings.ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement(base.XmlReader.LocalName, base.XmlReader.ODataNamespace)); } object item = this.ReadNonEntityValueImplementation(expectedTypeReference, duplicatePropertyNamesChecker, collectionValidator, true, false); base.XmlReader.Read(); ValidationUtils.ValidateCollectionItem(item, false); sourceEnumerable.Add(item); } else { base.XmlReader.Skip(); } break; case XmlNodeType.EndElement: break; default: base.XmlReader.Skip(); break; } }while (base.XmlReader.NodeType != XmlNodeType.EndElement); } value2.Items = new ReadOnlyEnumerable(sourceEnumerable); this.DecreaseRecursionDepth(); return(value2); }