示例#1
0
 /// <summary>
 /// Determines the type name to write to the payload.  Json Light type names are only written into the payload for open properties
 /// or if the payload type name is more derived than the model type name.
 /// </summary>
 /// <param name="value">The ODataValue whose type name is to be written.</param>
 /// <param name="propertyInfo">The serialization info of current property</param>
 /// <param name="isOpenProperty">true if the type name belongs to an open property, false otherwise.</param>
 /// <returns>Type name to write to the payload, or null if no type should be written.</returns>
 internal override string GetValueTypeNameForWriting(
     ODataValue value,
     PropertySerializationInfo propertyInfo,
     bool isOpenProperty)
 {
     return(null);
 }
        public void PropertyHandlerGetPropertyNullOwningType()
        {
            // Model with a single entity type
            EdmModel     model = new EdmModel();
            const string defaultNamespaceName = "Test";
            var          int32TypeRef         = EdmCoreModel.Instance.GetInt32(isNullable: false);

            // Create an entity with a complex type property.
            var singleComplexPropertyEntityType = new EdmEntityType(defaultNamespaceName, "SingleComplexPropertyEntityType");

            singleComplexPropertyEntityType.AddKeys(singleComplexPropertyEntityType.AddStructuralProperty("ID", int32TypeRef));
            model.AddElement(singleComplexPropertyEntityType);

            // Create a property handler, enter a resource set scope and update resource scope.
            PropertyCacheHandler handler = new PropertyCacheHandler();

            handler.SetCurrentResourceScopeLevel(1);
            handler.EnterResourceSetScope(singleComplexPropertyEntityType, 0);

            // Create a PropertySerializationInfo for ComplexProp.IntProp
            var info1 = handler.GetProperty("IntProp", null);

            info1.Should().NotBeNull();

            // Get a second PropertySerializationInfo for ComplexProp.IntProp; it should be the same.
            PropertySerializationInfo info2 = handler.GetProperty("IntProp", null);

            info2.Should().NotBeNull();
            info2.Should().BeSameAs(info1);
        }
示例#3
0
        /// <summary>
        /// Determines the type name to write to the payload.  Json Light type names are only written into the payload for open properties
        /// or if the payload type name is more derived than the model type name.
        /// </summary>
        /// <param name="value">The ODataValue whose type name is to be written.</param>
        /// <param name="propertyInfo">The serialization info of current property</param>
        /// <param name="isOpenProperty">true if the type name belongs to an open property, false otherwise.</param>
        /// <returns>Type name to write to the payload, or null if no type should be written.</returns>
        internal override string GetValueTypeNameForWriting(
            ODataValue value,
            PropertySerializationInfo propertyInfo,
            bool isOpenProperty)
        {
            PropertyValueTypeInfo valueType = propertyInfo.ValueType;

            string typeNameToWrite;

            if (TypeNameOracle.TryGetTypeNameFromAnnotation(value, out typeNameToWrite))
            {
                return(typeNameToWrite);
            }

            if (valueType.TypeReference != null)
            {
                // Do not write type name when the type is native json type.
                if (valueType.IsPrimitive && JsonSharedUtils.ValueTypeMatchesJsonType((ODataPrimitiveValue)value, valueType.PrimitiveTypeKind))
                {
                    return(null);
                }
            }

            return(GetTypeNameFromValue(value));
        }
        /// <summary>
        /// Determines the type name to write to the payload.  Json Light type names are only written into the payload for open properties
        /// or if the payload type name is more derived than the model type name.
        /// </summary>
        /// <param name="value">The ODataValue whose type name is to be written.</param>
        /// <param name="propertyInfo">The serialization info of current property</param>
        /// <param name="isOpenProperty">true if the type name belongs to an open property, false otherwise.</param>
        /// <returns>Type name to write to the payload, or null if no type should be written.</returns>
        internal override string GetValueTypeNameForWriting(
            ODataValue value,
            PropertySerializationInfo propertyInfo,
            bool isOpenProperty)
        {
            string fullTypeNameFromValue       = null;
            PropertyValueTypeInfo    valueType = propertyInfo.ValueType;
            PropertyMetadataTypeInfo modelType = propertyInfo.MetadataType;

            string typeNameToWrite;

            if (TypeNameOracle.TryGetTypeNameFromAnnotation(value, out typeNameToWrite))
            {
                return(typeNameToWrite);
            }

            if (valueType.TypeReference != null)
            {
                fullTypeNameFromValue = valueType.FullName;

                // Write type name when the type in the payload is more derived than the type from metadata.
                if (modelType.TypeReference != null && modelType.FullName != fullTypeNameFromValue)
                {
                    return(fullTypeNameFromValue);
                }

                // Do not write type name when the type is native json type.
                if (valueType.IsPrimitive && JsonSharedUtils.ValueTypeMatchesJsonType((ODataPrimitiveValue)value, valueType.PrimitiveTypeKind))
                {
                    return(null);
                }

                // Note: When writing derived complexType value in a payload, we don't have the expected type.
                // So always write @odata.type for top-level derived complex type.
                if (modelType.TypeReference == null && valueType.IsComplex)
                {
                    if ((valueType.TypeReference as IEdmComplexTypeReference).ComplexDefinition().BaseType != null)
                    {
                        return(fullTypeNameFromValue);
                    }
                }
            }

            if (!isOpenProperty)
            {
                // Do not write type name for non-open properties since we expect the reader to have an expected type (via API or context URI) and thus not need it.
                return(null);
            }

            return(fullTypeNameFromValue != null ? fullTypeNameFromValue : GetTypeNameFromValue(value));
        }
示例#5
0
        private PropertySerializationInfo GetSerializationInfo(Type type)
        {
            if (propertySerializationInfoHash == null)
            {
                propertySerializationInfoHash = new Hashtable();
            }
            if (propertySerializationInfoHash.Contains(type))
            {
                return((PropertySerializationInfo)propertySerializationInfoHash[type]);
            }
            PropertySerializationInfo info = new PropertySerializationInfo(type);

            propertySerializationInfoHash.Add(type, info);
            return(info);
        }
示例#6
0
        /// <summary>
        /// Writes the property information for a property.
        /// </summary>
        /// <param name="propertyInfo">The property info to write out.</param>
        /// <param name="owningType">The owning type for the <paramref name="propertyInfo"/> or null if no metadata is available.</param>
        /// <param name="isTopLevel">true when writing a top-level property; false for nested properties.</param>
        /// <param name="duplicatePropertyNameChecker">The DuplicatePropertyNameChecker to use.</param>
        /// <param name="metadataBuilder">The metadatabuilder for the resource</param>
        internal void WritePropertyInfo(
            ODataPropertyInfo propertyInfo,
            IEdmStructuredType owningType,
            bool isTopLevel,
            IDuplicatePropertyNameChecker duplicatePropertyNameChecker,
            ODataResourceMetadataBuilder metadataBuilder)
        {
            WriterValidationUtils.ValidatePropertyNotNull(propertyInfo);

            string propertyName = propertyInfo.Name;

            if (this.JsonLightOutputContext.MessageWriterSettings.Validations != ValidationKinds.None)
            {
                WriterValidationUtils.ValidatePropertyName(propertyName);
            }

            if (!this.JsonLightOutputContext.PropertyCacheHandler.InResourceSetScope())
            {
                this.currentPropertyInfo = new PropertySerializationInfo(this.JsonLightOutputContext.Model, propertyName, owningType)
                {
                    IsTopLevel = isTopLevel
                };
            }
            else
            {
                this.currentPropertyInfo = this.JsonLightOutputContext.PropertyCacheHandler.GetProperty(this.JsonLightOutputContext.Model, propertyName, owningType);
            }

            WriterValidationUtils.ValidatePropertyDefined(this.currentPropertyInfo, this.MessageWriterSettings.ThrowOnUndeclaredPropertyForNonOpenType);

            duplicatePropertyNameChecker.ValidatePropertyUniqueness(propertyInfo);

            if (currentPropertyInfo.MetadataType.IsUndeclaredProperty)
            {
                WriteODataTypeAnnotation(propertyInfo, isTopLevel);
            }

            WriteInstanceAnnotation(propertyInfo, isTopLevel, currentPropertyInfo.MetadataType.IsUndeclaredProperty);

            ODataStreamPropertyInfo streamInfo = propertyInfo as ODataStreamPropertyInfo;

            if (streamInfo != null && !(this.JsonLightOutputContext.MetadataLevel is JsonNoMetadataLevel))
            {
                Debug.Assert(!isTopLevel, "Stream properties are not allowed at the top level.");
                WriteStreamValue(streamInfo, propertyInfo.Name, metadataBuilder);
            }
        }
        private void WriteProperty(
            ODataProperty property,
            IEdmStructuredType owningType,
            bool isTopLevel,
            bool allowStreamProperty,
            IDuplicatePropertyNameChecker duplicatePropertyNameChecker)
        {
            WriterValidationUtils.ValidatePropertyNotNull(property);

            string propertyName = property.Name;

            if (this.JsonLightOutputContext.MessageWriterSettings.Validations != ValidationKinds.None)
            {
                WriterValidationUtils.ValidatePropertyName(propertyName);
            }

            if (!this.JsonLightOutputContext.PropertyCacheHandler.InResourceSetScope())
            {
                this.currentPropertyInfo = new PropertySerializationInfo(propertyName, owningType)
                {
                    IsTopLevel = isTopLevel
                };
            }
            else
            {
                this.currentPropertyInfo = this.JsonLightOutputContext.PropertyCacheHandler.GetProperty(propertyName, owningType);
            }

            WriterValidationUtils.ValidatePropertyDefined(this.currentPropertyInfo, this.MessageWriterSettings.ThrowOnUndeclaredPropertyForNonOpenType);

            duplicatePropertyNameChecker.ValidatePropertyUniqueness(property);

            if (currentPropertyInfo.MetadataType.IsUndeclaredProperty)
            {
                WriteODataTypeAnnotation(property, isTopLevel);
            }

            WriteInstanceAnnotation(property, isTopLevel, currentPropertyInfo.MetadataType.IsUndeclaredProperty);

            ODataValue value = property.ODataValue;

            // handle ODataUntypedValue
            ODataUntypedValue untypedValue = value as ODataUntypedValue;

            if (untypedValue != null)
            {
                WriteUntypedValue(untypedValue);
                return;
            }

            ODataStreamReferenceValue streamReferenceValue = value as ODataStreamReferenceValue;

            if (streamReferenceValue != null)
            {
                if (!allowStreamProperty)
                {
                    throw new ODataException(ODataErrorStrings.ODataWriter_StreamPropertiesMustBePropertiesOfODataResource(propertyName));
                }

                Debug.Assert(owningType == null || owningType.IsODataEntityTypeKind(), "The metadata should not allow named stream properties to be defined on a non-entity type.");
                Debug.Assert(!isTopLevel, "Stream properties are not allowed at the top level.");
                WriterValidationUtils.ValidateStreamReferenceProperty(property, currentPropertyInfo.MetadataType.EdmProperty, this.WritingResponse);
                this.WriteStreamReferenceProperty(propertyName, streamReferenceValue);
                return;
            }

            if (value is ODataNullValue || value == null)
            {
                this.WriteNullProperty(property);
                return;
            }

            bool isOpenPropertyType = this.IsOpenProperty(property);

            ODataPrimitiveValue primitiveValue = value as ODataPrimitiveValue;

            if (primitiveValue != null)
            {
                this.WritePrimitiveProperty(primitiveValue, isOpenPropertyType);
                return;
            }

            ODataEnumValue enumValue = value as ODataEnumValue;

            if (enumValue != null)
            {
                this.WriteEnumProperty(enumValue, isOpenPropertyType);
                return;
            }

            ODataCollectionValue collectionValue = value as ODataCollectionValue;

            if (collectionValue != null)
            {
                this.WriteCollectionProperty(collectionValue, isOpenPropertyType);
                return;
            }
        }
 /// <summary>
 /// Determines the type name to write to the payload.  Json Light type names are only written into the payload for open properties
 /// or if the payload type name is more derived than the model type name.
 /// </summary>
 /// <param name="value">The ODataValue whose type name is to be written.</param>
 /// <param name="propertyInfo">The serialization info of current property</param>
 /// <param name="isOpenProperty">true if the type name belongs to an open property, false otherwise.</param>
 /// <returns>Type name to write to the payload, or null if no type should be written.</returns>
 internal abstract string GetValueTypeNameForWriting(
     ODataValue value,
     PropertySerializationInfo propertyInfo,
     bool isOpenProperty);
 private PropertySerializationInfo GetSerializationInfo(Type type)
 {
     if (propertySerializationInfoHash == null)
     {
         propertySerializationInfoHash = new Hashtable();
     }
     if (propertySerializationInfoHash.Contains(type))
     {
         return (PropertySerializationInfo) propertySerializationInfoHash[type];
     }
     PropertySerializationInfo info = new PropertySerializationInfo(type);
     propertySerializationInfoHash.Add(type, info);
     return info;
 }
示例#10
0
        internal void DeserializeBody(XmlElement xmlElement, object obj)
        {
            object innerText;
            PropertySerializationInfo  serializationInfo = this.GetSerializationInfo(obj.GetType());
            IDataSourceXmlSpecialOwner owner             = obj as IDataSourceXmlSpecialOwner;

            foreach (XmlSerializableProperty property in serializationInfo.AttributeProperties)
            {
                DataSourceXmlAttributeAttribute serializationAttribute = property.SerializationAttribute as DataSourceXmlAttributeAttribute;
                if (serializationAttribute != null)
                {
                    XmlAttribute xmlNode = xmlElement.Attributes[property.Name];
                    if (xmlNode != null)
                    {
                        PropertyDescriptor propertyDescriptor = property.PropertyDescriptor;
                        if (serializationAttribute.SpecialWay)
                        {
                            owner.ReadSpecialItem(propertyDescriptor.Name, xmlNode, this);
                        }
                        else
                        {
                            Type propertyType = property.PropertyType;
                            if (propertyType == typeof(string))
                            {
                                innerText = xmlNode.InnerText;
                            }
                            else
                            {
                                innerText = TypeDescriptor.GetConverter(propertyType).ConvertFromString(xmlNode.InnerText);
                            }
                            if (innerText != null)
                            {
                                propertyDescriptor.SetValue(obj, innerText);
                            }
                        }
                    }
                }
            }
            foreach (XmlNode node in xmlElement.ChildNodes)
            {
                XmlElement element = node as XmlElement;
                if (element != null)
                {
                    XmlSerializableProperty serializablePropertyWithElementName = serializationInfo.GetSerializablePropertyWithElementName(element.LocalName);
                    if (serializablePropertyWithElementName != null)
                    {
                        PropertyDescriptor descriptor2 = serializablePropertyWithElementName.PropertyDescriptor;
                        DataSourceXmlSerializationAttribute attribute3 = serializablePropertyWithElementName.SerializationAttribute;
                        if (attribute3 is DataSourceXmlElementAttribute)
                        {
                            DataSourceXmlElementAttribute attribute1 = (DataSourceXmlElementAttribute)attribute3;
                            if (attribute3.SpecialWay)
                            {
                                owner.ReadSpecialItem(descriptor2.Name, element, this);
                            }
                            else if (this.NameToType.Contains(element.LocalName))
                            {
                                object obj3 = this.Deserialize(element);
                                descriptor2.SetValue(obj, obj3);
                            }
                            else
                            {
                                Type type = serializablePropertyWithElementName.PropertyType;
                                try
                                {
                                    if (type == typeof(string))
                                    {
                                        innerText = element.InnerText;
                                    }
                                    else
                                    {
                                        innerText = TypeDescriptor.GetConverter(type).ConvertFromString(element.InnerText);
                                    }
                                    descriptor2.SetValue(obj, innerText);
                                }
                                catch (Exception)
                                {
                                }
                            }
                        }
                        else
                        {
                            DataSourceXmlSubItemAttribute attribute4 = (DataSourceXmlSubItemAttribute)attribute3;
                            if (typeof(IList).IsAssignableFrom(descriptor2.PropertyType))
                            {
                                IList list = descriptor2.GetValue(obj) as IList;
                                foreach (XmlNode node2 in element.ChildNodes)
                                {
                                    XmlElement element2 = node2 as XmlElement;
                                    if (element2 != null)
                                    {
                                        object obj4 = this.Deserialize(element2);
                                        list.Add(obj4);
                                    }
                                }
                            }
                            else
                            {
                                for (XmlNode node3 = element.FirstChild; node3 != null; node3 = node3.NextSibling)
                                {
                                    if (node3 is XmlElement)
                                    {
                                        object obj5 = this.Deserialize((XmlElement)node3);
                                        descriptor2.SetValue(obj, obj5);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#11
0
 public FieldOrPropertyInfo(FieldSerializationInfo fieldSerializationInfo)
 {
     Result   = IndexerAccessResult.Field;
     Field    = fieldSerializationInfo;
     Property = default;
 }
示例#12
0
 public void Deconstruct(out IndexerAccessResult result, out FieldSerializationInfo field, out PropertySerializationInfo property)
 {
     result   = Result;
     field    = Field;
     property = Property;
 }
示例#13
0
 public FieldOrPropertyInfo(PropertySerializationInfo propertySerializationInfo)
 {
     Result   = IndexerAccessResult.Property;
     Field    = default;
     Property = propertySerializationInfo;
 }