/// <summary> /// Writes a Null property. /// </summary> /// <param name="property">The property to write out.</param> private void WriteNullProperty( ODataPropertyInfo property) { this.WriterValidator.ValidateNullPropertyValue( this.currentPropertyInfo.MetadataType.TypeReference, property.Name, this.currentPropertyInfo.IsTopLevel, this.Model); if (this.currentPropertyInfo.IsTopLevel) { if (this.JsonLightOutputContext.MessageWriterSettings.LibraryCompatibility < ODataLibraryCompatibility.Version7 && this.JsonLightOutputContext.MessageWriterSettings.Version < ODataVersion.V401) { // The 6.x library used an OData 3.0 protocol element in this case: @odata.null=true this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataNull); this.JsonWriter.WriteValue(true); } else { // From the spec: // 11.2.3 Requesting Individual Properties // ... // If the property is single-valued and has the null value, the service responds with 204 No Content. // ... throw new ODataException(Strings.ODataMessageWriter_CannotWriteTopLevelNull); } } else { this.JsonWriter.WriteName(property.Name); this.JsonLightValueSerializer.WriteNullValue(); } }
/// <summary> /// Writes instance annotation for property /// </summary> /// <param name="property">The property to handle.</param> /// <param name="isTopLevel">If writing top level property.</param> /// <param name="isUndeclaredProperty">If writing an undeclared property.</param> private void WriteInstanceAnnotation(ODataPropertyInfo property, bool isTopLevel, bool isUndeclaredProperty) { if (property.InstanceAnnotations.Count != 0) { if (isTopLevel) { this.InstanceAnnotationWriter.WriteInstanceAnnotations(property.InstanceAnnotations); } else { this.InstanceAnnotationWriter.WriteInstanceAnnotations(property.InstanceAnnotations, property.Name, isUndeclaredProperty); } } }
/// <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); } }
public ODataJsonLightPropertySerializerAsyncTests() { // Initialize open EntityType: EntityType. EdmModel edmModel = new EdmModel(); EdmEntityType edmEntityType = new EdmEntityType("NS", "EntityType", baseType: null, isAbstract: false, isOpen: true); edmEntityType.AddStructuralProperty("DeclaredProperty", EdmPrimitiveTypeKind.Int32); edmModel.AddElement(edmEntityType); this.model = TestUtils.WrapReferencedModelsToMainModel(edmModel); this.entityType = edmEntityType; this.declaredPropertyWithInstanceAnnotations = new ODataProperty() { Name = "DeclaredProperty", Value = 12345, InstanceAnnotations = new Collection <ODataInstanceAnnotation> { new ODataInstanceAnnotation("Is.Numeric", new ODataPrimitiveValue(true)), new ODataInstanceAnnotation("Is.ReadOnly", new ODataPrimitiveValue(false)) } }; this.undeclaredPropertyWithInstanceAnnotations = new ODataProperty { Name = "UndeclaredProperty", Value = (long)13, TypeAnnotation = new ODataTypeAnnotation(EdmCoreModel.Instance.GetInt64(false).FullName()), InstanceAnnotations = new Collection <ODataInstanceAnnotation> { new ODataInstanceAnnotation("Is.LuckyNumber", new ODataPrimitiveValue(true)) } }; this.streamProperty = new ODataStreamPropertyInfo { Name = "StreamProp", ContentType = "image/jpeg", EditLink = new Uri("http://tempuri.org/stream/edit"), ReadLink = new Uri("http://tempuri.org/stream/read"), ETag = "Stream Etag" }; }
/// <summary> /// Writes odata type annotation for property /// </summary> /// <param name="property">The property to handle.</param> /// <param name="isTopLevel">If writing top level property.</param> private void WriteODataTypeAnnotation(ODataPropertyInfo property, bool isTopLevel) { if (property.TypeAnnotation != null && property.TypeAnnotation.TypeName != null) { string typeName = property.TypeAnnotation.TypeName; IEdmPrimitiveType primitiveType = EdmCoreModel.Instance.FindType(typeName) as IEdmPrimitiveType; if (primitiveType == null || (primitiveType.PrimitiveKind != EdmPrimitiveTypeKind.String && primitiveType.PrimitiveKind != EdmPrimitiveTypeKind.Decimal && primitiveType.PrimitiveKind != EdmPrimitiveTypeKind.Boolean)) { if (isTopLevel) { this.ODataAnnotationWriter.WriteODataTypeInstanceAnnotation(typeName); } else { this.ODataAnnotationWriter.WriteODataTypePropertyAnnotation(property.Name, typeName); } } } }
/// <summary> /// Test to see if <paramref name="property"/> is an open property or not. /// </summary> /// <param name="property">The property in question.</param> /// <returns>true if the property is an open property; false if it is not, or if openness cannot be determined</returns> private bool IsOpenProperty(ODataPropertyInfo property) { Debug.Assert(property != null, "property != null"); bool isOpenProperty; if (property.SerializationInfo != null) { isOpenProperty = property.SerializationInfo.PropertyKind == ODataPropertyKind.Open; } else { // TODO: (issue #888) this logic results in type annotations not being written for dynamic properties on types that are not // marked as open. Type annotations should always be written for dynamic properties whose type cannot be hueristically // determined. Need to change this.currentPropertyInfo.MetadataType.IsOpenProperty to this.currentPropertyInfo.MetadataType.IsDynamic, // and fix related tests and other logic (this change alone results in writing type even if it's already implied by context). isOpenProperty = (!this.WritingResponse && this.currentPropertyInfo.MetadataType.OwningType == null) || // Treat property as dynamic property when writing request and owning type is null this.currentPropertyInfo.MetadataType.IsOpenProperty; } return(isOpenProperty); }
internal ODataJsonLightReaderNestedPropertyInfo(ODataPropertyInfo nestedPropertyInfo, IEdmProperty nestedProperty) : base(nestedProperty) { this.NestedPropertyInfo = nestedPropertyInfo; }