private void ReadPropertiesImplementation(IEdmStructuredType structuredType, List <ODataProperty> properties, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, bool epmPresent) { if (!base.XmlReader.IsEmptyElement) { base.XmlReader.ReadStartElement(); do { switch (base.XmlReader.NodeType) { case XmlNodeType.Element: if (base.XmlReader.NamespaceEquals(base.XmlReader.ODataNamespace)) { IEdmProperty property = null; bool flag = false; bool ignoreProperty = false; if (structuredType != null) { property = ReaderValidationUtils.ValidateValuePropertyDefined(base.XmlReader.LocalName, structuredType, base.MessageReaderSettings, out ignoreProperty); if ((property != null) && (property.PropertyKind == EdmPropertyKind.Navigation)) { throw new ODataException(Microsoft.Data.OData.Strings.ODataAtomPropertyAndValueDeserializer_NavigationPropertyInProperties(property.Name, structuredType)); } flag = property == null; } if (ignoreProperty) { base.XmlReader.Skip(); } else { ODataNullValueBehaviorKind nullValueReadBehaviorKind = (base.ReadingResponse || (property == null)) ? ODataNullValueBehaviorKind.Default : base.Model.NullValueReadBehaviorKind(property); ODataProperty property2 = this.ReadProperty((property == null) ? null : property.Type, nullValueReadBehaviorKind, epmPresent); if (property2 != null) { if (flag) { ValidationUtils.ValidateOpenPropertyValue(property2.Name, property2.Value); } duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property2); properties.Add(property2); } } } else { base.XmlReader.Skip(); } break; case XmlNodeType.EndElement: break; default: base.XmlReader.Skip(); break; } }while (base.XmlReader.NodeType != XmlNodeType.EndElement); } }
private void ReadEntryProperty(IODataJsonReaderEntryState entryState, IEdmProperty edmProperty) { ODataNullValueBehaviorKind kind = base.ReadingResponse ? ODataNullValueBehaviorKind.Default : base.Model.NullValueReadBehaviorKind(edmProperty); IEdmTypeReference type = edmProperty.Type; object propertyValue = type.IsStream() ? this.ReadStreamPropertyValue() : base.ReadNonEntityValue(type, null, null, kind == ODataNullValueBehaviorKind.Default); if ((kind != ODataNullValueBehaviorKind.IgnoreValue) || (propertyValue != null)) { AddEntryProperty(entryState, edmProperty.Name, propertyValue); } }
/// <summary> /// Reads a property. /// </summary> /// <param name="isTop">whether it is the top level</param> /// <param name="expectedPropertyName">The expected property name to be read from the payload (or null if no expected property name was specified).</param> /// <param name="expectedPropertyTypeReference">The expected type reference of the property value.</param> /// <param name="nullValueReadBehaviorKind">Behavior to use when reading null value for the property.</param> /// <returns>The ODataProperty representing the property in question; if null is returned from this method it means that the property is to be ignored.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element - The XML element representing the property to read. /// Note that the method does NOT check for the property name neither it resolves the property against metadata. /// Post-Condition: Any - The node after the property. /// </remarks> private ODataProperty ReadProperty( bool isTop, string expectedPropertyName, IEdmTypeReference expectedPropertyTypeReference, ODataNullValueBehaviorKind nullValueReadBehaviorKind) { Debug.Assert( expectedPropertyTypeReference == null || expectedPropertyTypeReference.IsODataPrimitiveTypeKind() || expectedPropertyTypeReference.IsODataEnumTypeKind() || expectedPropertyTypeReference.IsODataComplexTypeKind() || expectedPropertyTypeReference.IsNonEntityCollectionType(), "Only primitive, Enum, complex and collection types can be read by this method."); this.AssertXmlCondition(XmlNodeType.Element); this.XmlReader.AssertNotBuffering(); ODataProperty property = new ODataProperty(); string propertyName = null; if (!isTop) { propertyName = this.XmlReader.LocalName; ValidationUtils.ValidatePropertyName(propertyName); ReaderValidationUtils.ValidateExpectedPropertyName(expectedPropertyName, propertyName); } property.Name = propertyName; object propertyValue = this.ReadNonEntityValueImplementation( expectedPropertyTypeReference, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default, propertyName); if (nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue && propertyValue == null) { property = null; } else { property.Value = propertyValue; } // Read past the end tag of the property or the start tag if the element is empty. this.XmlReader.Read(); this.XmlReader.AssertNotBuffering(); return(property); }
/// <summary> /// Reads a property. /// </summary> /// <param name="expectedPropertyName">The expected property name to be read from the payload (or null if no expected property name was specified).</param> /// <param name="expectedPropertyTypeReference">The expected type reference of the property value.</param> /// <param name="nullValueReadBehaviorKind">Behavior to use when reading null value for the property.</param> /// <param name="epmPresent">Whether any EPM mappings exist.</param> /// <returns>The ODataProperty representing the property in question; if null is returned from this method it means that the property is to be ignored.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element - The XML element representing the property to read. /// Note that the method does NOT check for the property name neither it resolves the property against metadata. /// Post-Condition: Any - The node after the property. /// </remarks> private ODataProperty ReadProperty( string expectedPropertyName, IEdmTypeReference expectedPropertyTypeReference, ODataNullValueBehaviorKind nullValueReadBehaviorKind, bool epmPresent) { Debug.Assert( expectedPropertyTypeReference == null || expectedPropertyTypeReference.IsODataPrimitiveTypeKind() || expectedPropertyTypeReference.IsODataComplexTypeKind() || expectedPropertyTypeReference.IsNonEntityCollectionType(), "Only primitive, complex and collection types can be read by this method."); this.AssertXmlCondition(XmlNodeType.Element); Debug.Assert(this.UseServerFormatBehavior || this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace), "Property elements must be in the OData namespace (unless we are running in WCF DS server format mode)."); this.XmlReader.AssertNotBuffering(); ODataProperty property = new ODataProperty(); string propertyName = this.XmlReader.LocalName; ValidationUtils.ValidatePropertyName(propertyName); ReaderValidationUtils.ValidateExpectedPropertyName(expectedPropertyName, propertyName); property.Name = propertyName; object propertyValue = this.ReadNonEntityValueImplementation( expectedPropertyTypeReference, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default, epmPresent, propertyName); if (nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue && propertyValue == null) { property = null; } else { property.Value = propertyValue; } // Read past the end tag of the property or the start tag if the element is empty. this.XmlReader.Read(); this.XmlReader.AssertNotBuffering(); return(property); }
/// <summary> /// Adds a transient annotation to indicate how null values for the specified property should be read. /// </summary> /// <param name="model">The <see cref="IEdmModel"/> containing the annotations.</param> /// <param name="property">The <see cref="IEdmProperty"/> to modify.</param> /// <param name="nullValueReadBehaviorKind">The new behavior for reading null values for this property.</param> public static void SetNullValueReaderBehavior(this IEdmModel model, IEdmProperty property, ODataNullValueBehaviorKind nullValueReadBehaviorKind) { ExceptionUtils.CheckArgumentNotNull(model, "model"); ExceptionUtils.CheckArgumentNotNull(property, "property"); ODataEdmPropertyAnnotation annotation = model.GetAnnotationValue<ODataEdmPropertyAnnotation>(property); if (annotation == null) { if (nullValueReadBehaviorKind != ODataNullValueBehaviorKind.Default) { annotation = new ODataEdmPropertyAnnotation { NullValueReadBehaviorKind = nullValueReadBehaviorKind }; model.SetAnnotationValue(property, annotation); } } else { annotation.NullValueReadBehaviorKind = nullValueReadBehaviorKind; } }
/// <summary> /// Reads the content of a properties in an element (complex value, m:properties, ...) /// </summary> /// <param name="structuredType">The type which should declare the properties to be read. Optional.</param> /// <param name="properties">The list of properties to add properties to.</param> /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use.</param> /// <param name="epmPresent">Whether any EPM mappings exist.</param> /// <remarks> /// Pre-Condition: XmlNodeType.Element - The element to read properties from. /// Post-Condition: XmlNodeType.Element - The element to read properties from if it is an empty element. /// XmlNodeType.EndElement - The end element of the element to read properties from. /// </remarks> private void ReadPropertiesImplementation(IEdmStructuredType structuredType, List <ODataProperty> properties, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, bool epmPresent) { Debug.Assert(properties != null, "properties != null"); Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null"); this.AssertXmlCondition(XmlNodeType.Element); // Empty values are valid - they have no properties if (!this.XmlReader.IsEmptyElement) { // Read over the complex value element to its first child node (or end-element) this.XmlReader.ReadStartElement(); do { switch (this.XmlReader.NodeType) { case XmlNodeType.Element: if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace)) { // Found a property IEdmProperty edmProperty = null; bool isOpen = false; bool ignoreProperty = false; if (structuredType != null) { // Lookup the property in metadata edmProperty = ReaderValidationUtils.ValidateValuePropertyDefined(this.XmlReader.LocalName, structuredType, this.MessageReaderSettings, out ignoreProperty); if (edmProperty != null && edmProperty.PropertyKind == EdmPropertyKind.Navigation) { throw new ODataException(o.Strings.ODataAtomPropertyAndValueDeserializer_NavigationPropertyInProperties(edmProperty.Name, structuredType)); } // If the property was not declared, it must be open. isOpen = edmProperty == null; } if (ignoreProperty) { this.XmlReader.Skip(); } else { ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse || edmProperty == null ? ODataNullValueBehaviorKind.Default : this.Model.NullValueReadBehaviorKind(edmProperty); ODataProperty property = this.ReadProperty(edmProperty == null ? null : edmProperty.Type, nullValueReadBehaviorKind, epmPresent); Debug.Assert( property != null || nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue, "If we don't ignore null values the property must not be null."); if (property != null) { if (isOpen) { ValidationUtils.ValidateOpenPropertyValue(property.Name, property.Value); } duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property); properties.Add(property); } } } else { this.XmlReader.Skip(); } break; case XmlNodeType.EndElement: // End of the complex value. break; default: // Non-element so for example a text node, just ignore this.XmlReader.Skip(); break; } }while (this.XmlReader.NodeType != XmlNodeType.EndElement); } }
/// <summary> /// Adds a transient annotation to indicate how null values for the specified property should be read. /// </summary> /// <param name="model">The <see cref="IEdmModel"/> containing the annotations.</param> /// <param name="property">The <see cref="IEdmProperty"/> to modify.</param> /// <param name="nullValueReadBehaviorKind">The new behavior for reading null values for this property.</param> public static void SetNullValueReaderBehavior(this IEdmModel model, IEdmProperty property, ODataNullValueBehaviorKind nullValueReadBehaviorKind) { ExceptionUtils.CheckArgumentNotNull(model, "model"); ExceptionUtils.CheckArgumentNotNull(property, "property"); ODataEdmPropertyAnnotation annotation = model.GetAnnotationValue <ODataEdmPropertyAnnotation>(property); if (annotation == null) { if (nullValueReadBehaviorKind != ODataNullValueBehaviorKind.Default) { annotation = new ODataEdmPropertyAnnotation { NullValueReadBehaviorKind = nullValueReadBehaviorKind }; model.SetAnnotationValue(property, annotation); } } else { annotation.NullValueReadBehaviorKind = nullValueReadBehaviorKind; } }
/// <summary> /// Reads a property. /// </summary> /// <param name="isTop">whether it is the top level</param> /// <param name="expectedPropertyName">The expected property name to be read from the payload (or null if no expected property name was specified).</param> /// <param name="expectedPropertyTypeReference">The expected type reference of the property value.</param> /// <param name="nullValueReadBehaviorKind">Behavior to use when reading null value for the property.</param> /// <returns>The ODataProperty representing the property in question; if null is returned from this method it means that the property is to be ignored.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element - The XML element representing the property to read. /// Note that the method does NOT check for the property name neither it resolves the property against metadata. /// Post-Condition: Any - The node after the property. /// </remarks> private ODataProperty ReadProperty( bool isTop, string expectedPropertyName, IEdmTypeReference expectedPropertyTypeReference, ODataNullValueBehaviorKind nullValueReadBehaviorKind) { Debug.Assert( expectedPropertyTypeReference == null || expectedPropertyTypeReference.IsODataPrimitiveTypeKind() || expectedPropertyTypeReference.IsODataEnumTypeKind() || expectedPropertyTypeReference.IsODataComplexTypeKind() || expectedPropertyTypeReference.IsNonEntityCollectionType(), "Only primitive, Enum, complex and collection types can be read by this method."); this.AssertXmlCondition(XmlNodeType.Element); this.XmlReader.AssertNotBuffering(); ODataProperty property = new ODataProperty(); string propertyName = null; if (!isTop) { propertyName = this.XmlReader.LocalName; ValidationUtils.ValidatePropertyName(propertyName); ReaderValidationUtils.ValidateExpectedPropertyName(expectedPropertyName, propertyName); } property.Name = propertyName; object propertyValue = this.ReadNonEntityValueImplementation( expectedPropertyTypeReference, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default, propertyName); if (nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue && propertyValue == null) { property = null; } else { property.Value = propertyValue; } // Read past the end tag of the property or the start tag if the element is empty. this.XmlReader.Read(); this.XmlReader.AssertNotBuffering(); return property; }
/// <summary> /// Reads a complex value. /// </summary> /// <param name="complexValueTypeReference">The expected type reference of the value.</param> /// <param name="payloadTypeName">The type name read from the payload.</param> /// <param name="serializationTypeNameAnnotation">The serialization type name for the collection value (possibly null).</param> /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use - if null the method should create a new one if necessary.</param> /// <returns>The value of the complex value.</returns> /// <remarks> /// Pre-Condition: Fails if the current node is not a JsonNodeType.StartObject or JsonNodeType.PrimitiveValue (with null value) /// Post-Condition: almost anything - the node after the complex value (after the EndObject) /// </remarks> private ODataComplexValue ReadComplexValueImplementation( IEdmComplexTypeReference complexValueTypeReference, string payloadTypeName, SerializationTypeNameAnnotation serializationTypeNameAnnotation, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker) { this.JsonReader.AssertNotBuffering(); this.IncreaseRecursionDepth(); // Read over the start object this.JsonReader.ReadStartObject(); ODataComplexValue complexValue = new ODataComplexValue(); complexValue.TypeName = complexValueTypeReference != null?complexValueTypeReference.ODataFullName() : payloadTypeName; if (serializationTypeNameAnnotation != null) { complexValue.SetAnnotation(serializationTypeNameAnnotation); } if (duplicatePropertyNamesChecker == null) { duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker(); } else { duplicatePropertyNamesChecker.Clear(); } List <ODataProperty> properties = new List <ODataProperty>(); bool metadataPropertyFound = false; while (this.JsonReader.NodeType == JsonNodeType.Property) { string propertyName = this.JsonReader.ReadPropertyName(); if (string.CompareOrdinal(JsonConstants.ODataMetadataName, propertyName) == 0) { // __metadata property. if (metadataPropertyFound) { throw new ODataException(ODataErrorStrings.ODataJsonPropertyAndValueDeserializer_MultipleMetadataPropertiesInComplexValue); } metadataPropertyFound = true; this.JsonReader.SkipValue(); } else { if (!ValidationUtils.IsValidPropertyName(propertyName)) { // We ignore properties with an invalid name since these are extension points for the future. this.JsonReader.SkipValue(); } else { // Any other property is data ODataProperty property = new ODataProperty(); property.Name = propertyName; // Lookup the property in metadata IEdmProperty edmProperty = null; bool ignoreProperty = false; if (complexValueTypeReference != null) { edmProperty = ReaderValidationUtils.ValidateValuePropertyDefined(propertyName, complexValueTypeReference.ComplexDefinition(), this.MessageReaderSettings, out ignoreProperty); } if (ignoreProperty) { // in case of ignoreProperty = true which means to ignore undeclared property. this.JsonReader.SkipValue(); } else { ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse || edmProperty == null ? ODataNullValueBehaviorKind.Default : this.Model.NullValueReadBehaviorKind(edmProperty); // Read the property value object propertyValue = this.ReadNonEntityValueImplementation( edmProperty == null ? null : edmProperty.Type, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default, propertyName); if (nullValueReadBehaviorKind != ODataNullValueBehaviorKind.IgnoreValue || propertyValue != null) { duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property); property.Value = propertyValue; properties.Add(property); } } } } } Debug.Assert(this.JsonReader.NodeType == JsonNodeType.EndObject, "After all the properties of a complex value are read the EndObject node is expected."); this.JsonReader.ReadEndObject(); complexValue.Properties = new ReadOnlyEnumerable <ODataProperty>(properties); this.JsonReader.AssertNotBuffering(); this.DecreaseRecursionDepth(); return(complexValue); }
/// <summary> /// Reads the content of a properties in an element (complex value, m:properties, ...) /// </summary> /// <param name="structuredType">The type which should declare the properties to be read. Optional.</param> /// <param name="properties">The list of properties to add properties to.</param> /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use.</param> /// <remarks> /// Pre-Condition: XmlNodeType.Element - The element to read properties from. /// Post-Condition: XmlNodeType.Element - The element to read properties from if it is an empty element. /// XmlNodeType.EndElement - The end element of the element to read properties from. /// </remarks> private void ReadPropertiesImplementation(IEdmStructuredType structuredType, ReadOnlyEnumerable <ODataProperty> properties, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker) { Debug.Assert(properties != null, "properties != null"); Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null"); this.AssertXmlCondition(XmlNodeType.Element); // Empty values are valid - they have no properties if (!this.XmlReader.IsEmptyElement) { // Read over the complex value element to its first child node (or end-element) this.XmlReader.ReadStartElement(); // WCF DS will skip over the rest of the complex value or entity properties if the first element in it is preceded with // a text node. Once the first element is found (no matter its namespace) then the non-element nodes // are ignored but skipped and the reading continues. // For ODataLib we should not do this and probably just ignore the text node even at the beginning (to be consistent). do { switch (this.XmlReader.NodeType) { case XmlNodeType.Element: if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace)) { // Found a property IEdmProperty edmProperty = null; bool isOpen = false; bool ignoreProperty = false; if (structuredType != null) { // Lookup the property in metadata edmProperty = ReaderValidationUtils.ValidateValuePropertyDefined(this.XmlReader.LocalName, structuredType, this.MessageReaderSettings, out ignoreProperty); if (edmProperty != null && edmProperty.PropertyKind == EdmPropertyKind.Navigation) { throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueDeserializer_NavigationPropertyInProperties(edmProperty.Name, structuredType)); } // If the property was not declared, it must be open. isOpen = edmProperty == null; } if (ignoreProperty) { this.XmlReader.Skip(); } else { // EdmLib bridge marks all key properties as non-nullable, but Astoria allows them to be nullable. // If the property has an annotation to ignore null values, we need to omit the property in requests. ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse || edmProperty == null ? ODataNullValueBehaviorKind.Default : this.Model.NullValueReadBehaviorKind(edmProperty); ODataProperty property = this.ReadProperty( false, edmProperty == null ? null : edmProperty.Name, edmProperty == null ? null : edmProperty.Type, nullValueReadBehaviorKind); Debug.Assert( property != null || nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue, "If we don't ignore null values the property must not be null."); if (property != null) { if (isOpen) { ValidationUtils.ValidateOpenPropertyValue(property.Name, property.Value); } duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property); properties.AddToSourceList(property); } } } else { this.XmlReader.Skip(); } break; case XmlNodeType.EndElement: // End of the complex value. break; default: // Non-element so for example a text node, just ignore this.XmlReader.Skip(); break; } }while (this.XmlReader.NodeType != XmlNodeType.EndElement); } }
private ODataComplexValue ReadComplexValueImplementation(IEdmComplexTypeReference complexValueTypeReference, string payloadTypeName, SerializationTypeNameAnnotation serializationTypeNameAnnotation, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker) { this.IncreaseRecursionDepth(); base.JsonReader.ReadStartObject(); ODataComplexValue value2 = new ODataComplexValue { TypeName = (complexValueTypeReference != null) ? complexValueTypeReference.ODataFullName() : payloadTypeName }; if (serializationTypeNameAnnotation != null) { value2.SetAnnotation <SerializationTypeNameAnnotation>(serializationTypeNameAnnotation); } if (duplicatePropertyNamesChecker == null) { duplicatePropertyNamesChecker = base.CreateDuplicatePropertyNamesChecker(); } else { duplicatePropertyNamesChecker.Clear(); } List <ODataProperty> sourceList = new List <ODataProperty>(); bool flag = false; while (base.JsonReader.NodeType == JsonNodeType.Property) { string strB = base.JsonReader.ReadPropertyName(); if (string.CompareOrdinal("__metadata", strB) == 0) { if (flag) { throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonPropertyAndValueDeserializer_MultipleMetadataPropertiesInComplexValue); } flag = true; base.JsonReader.SkipValue(); } else if (!ValidationUtils.IsValidPropertyName(strB)) { base.JsonReader.SkipValue(); } else { ODataProperty property = new ODataProperty { Name = strB }; IEdmProperty property2 = null; bool ignoreProperty = false; if (complexValueTypeReference != null) { property2 = ReaderValidationUtils.ValidateValuePropertyDefined(strB, complexValueTypeReference.ComplexDefinition(), base.MessageReaderSettings, out ignoreProperty); } if (ignoreProperty) { base.JsonReader.SkipValue(); continue; } ODataNullValueBehaviorKind kind = (base.ReadingResponse || (property2 == null)) ? ODataNullValueBehaviorKind.Default : base.Model.NullValueReadBehaviorKind(property2); object obj2 = this.ReadNonEntityValueImplementation((property2 == null) ? null : property2.Type, null, null, kind == ODataNullValueBehaviorKind.Default); if ((kind != ODataNullValueBehaviorKind.IgnoreValue) || (obj2 != null)) { duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property); property.Value = obj2; sourceList.Add(property); } } } base.JsonReader.ReadEndObject(); value2.Properties = new ReadOnlyEnumerable <ODataProperty>(sourceList); this.DecreaseRecursionDepth(); return(value2); }
private ODataProperty ReadProperty(IEdmTypeReference expectedPropertyTypeReference, ODataNullValueBehaviorKind nullValueReadBehaviorKind, bool epmPresent) { ODataProperty property = new ODataProperty(); string localName = base.XmlReader.LocalName; ValidationUtils.ValidatePropertyName(localName); property.Name = localName; object obj2 = this.ReadNonEntityValueImplementation(expectedPropertyTypeReference, null, null, nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default, epmPresent); if ((nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue) && (obj2 == null)) { property = null; } else { property.Value = obj2; } base.XmlReader.Read(); return(property); }
private IEdmProperty CreateProperty(EdmStructuredType declaringType, ResourceProperty resourceProperty) { IEdmProperty property; List <KeyValuePair <string, object> > annotations = (resourceProperty.CustomAnnotations == null) ? null : resourceProperty.CustomAnnotations.ToList <KeyValuePair <string, object> >(); ODataNullValueBehaviorKind nullValueReadBehaviorKind = ODataNullValueBehaviorKind.Default; if (resourceProperty.IsOfKind(ResourcePropertyKind.Primitive) || resourceProperty.IsOfKind(ResourcePropertyKind.Stream)) { IEdmPrimitiveTypeReference typeReference = MetadataProviderUtils.CreatePrimitiveTypeReference(resourceProperty.ResourceType, annotations); if (resourceProperty.IsOfKind(ResourcePropertyKind.Key)) { if (typeReference.IsNullable) { typeReference = (IEdmPrimitiveTypeReference)typeReference.Clone(false); } nullValueReadBehaviorKind = ODataNullValueBehaviorKind.IgnoreValue; } else if (MetadataProviderUtils.ShouldDisablePrimitivePropertyNullValidation(resourceProperty, typeReference)) { nullValueReadBehaviorKind = ODataNullValueBehaviorKind.DisableValidation; } string andRemoveDefaultValue = MetadataProviderUtils.GetAndRemoveDefaultValue(annotations); EdmConcurrencyMode concurrencyMode = resourceProperty.IsOfKind(ResourcePropertyKind.ETag) ? EdmConcurrencyMode.Fixed : EdmConcurrencyMode.None; property = declaringType.AddStructuralProperty(resourceProperty.Name, typeReference, andRemoveDefaultValue, concurrencyMode); string mimeType = resourceProperty.MimeType; if (!string.IsNullOrEmpty(mimeType)) { this.SetMimeType(property, mimeType); } } else if (resourceProperty.IsOfKind(ResourcePropertyKind.ComplexType)) { IEdmTypeReference reference2 = this.EnsureTypeReference(resourceProperty.ResourceType, annotations); string defaultValue = MetadataProviderUtils.GetAndRemoveDefaultValue(annotations); property = declaringType.AddStructuralProperty(resourceProperty.Name, reference2, defaultValue, EdmConcurrencyMode.None); if (this.metadataProvider.IsV1Provider && !reference2.IsNullable) { nullValueReadBehaviorKind = ODataNullValueBehaviorKind.DisableValidation; } } else if (resourceProperty.IsOfKind(ResourcePropertyKind.Collection)) { string str4 = MetadataProviderUtils.GetAndRemoveDefaultValue(annotations); IEdmTypeReference reference3 = this.EnsureTypeReference(resourceProperty.ResourceType, annotations); property = declaringType.AddStructuralProperty(resourceProperty.Name, reference3, str4, EdmConcurrencyMode.None); } else { if (!resourceProperty.IsOfKind(ResourcePropertyKind.ResourceSetReference) && !resourceProperty.IsOfKind(ResourcePropertyKind.ResourceReference)) { throw new InvalidOperationException(System.Data.Services.Strings.MetadataProviderEdmModel_UnsupportedResourcePropertyKind(resourceProperty.Kind.ToString())); } EdmEntityType type = (EdmEntityType)declaringType; IEdmTypeReference reference4 = resourceProperty.IsOfKind(ResourcePropertyKind.ResourceSetReference) ? this.EnsureEntityPrimitiveOrComplexCollectionTypeReference(resourceProperty.ResourceType, annotations) : this.EnsureTypeReference(resourceProperty.ResourceType, annotations); property = new MetadataProviderEdmNavigationProperty(type, resourceProperty.Name, reference4); type.AddProperty(property); } this.SetNullValueReaderBehavior(property, nullValueReadBehaviorKind); MetadataProviderUtils.ConvertCustomAnnotations(this, annotations, property); return(property); }
/// <summary> /// Reads a property. /// </summary> /// <param name="expectedPropertyTypeReference">The expected type reference of the property value.</param> /// <param name="nullValueReadBehaviorKind">Behavior to use when reading null value for the property.</param> /// <param name="epmPresent">Whether any EPM mappings exist.</param> /// <returns>The ODataProperty representing the property in question; if null is returned from this method it means that the property is to be ignored.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element - The XML element representing the property to read. /// Note that the method does NOT check for the property name neither it resolves the property against metadata. /// Post-Condition: Any - The node after the property. /// </remarks> private ODataProperty ReadProperty(IEdmTypeReference expectedPropertyTypeReference, ODataNullValueBehaviorKind nullValueReadBehaviorKind, bool epmPresent) { Debug.Assert( expectedPropertyTypeReference == null || expectedPropertyTypeReference.IsODataPrimitiveTypeKind() || expectedPropertyTypeReference.IsODataComplexTypeKind() || expectedPropertyTypeReference.IsNonEntityODataCollectionTypeKind(), "Only primitive, complex and collection types can be read by this method."); this.AssertXmlCondition(XmlNodeType.Element); Debug.Assert(this.UseServerFormatBehavior || this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace), "Property elements must be in the OData namespace (unless we are running in WCF DS server format mode)."); this.XmlReader.AssertNotBuffering(); ODataProperty property = new ODataProperty(); string propertyName = this.XmlReader.LocalName; ValidationUtils.ValidatePropertyName(propertyName); property.Name = propertyName; object propertyValue = this.ReadNonEntityValueImplementation( expectedPropertyTypeReference, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default, epmPresent); if (nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue && propertyValue == null) { property = null; } else { property.Value = propertyValue; } // Read past the end tag of the property or the start tag if the element is empty. this.XmlReader.Read(); this.XmlReader.AssertNotBuffering(); return property; }
private ODataProperty ReadProperty(IEdmTypeReference expectedPropertyTypeReference, ODataNullValueBehaviorKind nullValueReadBehaviorKind, bool epmPresent) { ODataProperty property = new ODataProperty(); string localName = base.XmlReader.LocalName; ValidationUtils.ValidatePropertyName(localName); property.Name = localName; object obj2 = this.ReadNonEntityValueImplementation(expectedPropertyTypeReference, null, null, nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default, epmPresent); if ((nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue) && (obj2 == null)) { property = null; } else { property.Value = obj2; } base.XmlReader.Read(); return property; }