public void OnlyCustomAnnotationsForPropertyAddedShouldReturnNull() { DuplicatePropertyNamesChecker duplicateChecker = new DuplicatePropertyNamesChecker(false, true); duplicateChecker.AddCustomPropertyAnnotation("property", "custom.annotation"); duplicateChecker.AddCustomPropertyAnnotation("property", "custom.annotation2"); duplicateChecker.GetODataPropertyAnnotations("property").Should().BeNull(); }
/// <summary> /// Reads a property value which occurs in the "error" object scope. /// </summary> /// <param name="error">The <see cref="ODataError"/> object to update with the data from this property value.</param> /// <param name="propertyName">The name of the property whose value is to be read.</param> /// <param name="duplicationPropertyNameChecker">DuplicatePropertyNamesChecker to use for extracting property annotations /// targetting any custom instance annotations on the error.</param> /// <remarks> /// Pre-Condition: any - The value of the property being read. /// Post-Condition: JsonNodeType.Property - The property after the one being read. /// JsonNodeType.EndObject - The end of the "error" object. /// any - Anything else after the property value is an invalid payload (but won't fail in this method). /// </remarks> private void ReadPropertyValueInODataErrorObject(ODataError error, string propertyName, DuplicatePropertyNamesChecker duplicationPropertyNameChecker) { switch (propertyName) { case JsonConstants.ODataErrorCodeName: error.ErrorCode = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorCodeName); break; case JsonConstants.ODataErrorMessageName: error.Message = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorMessageName); break; case JsonConstants.ODataErrorTargetName: error.Target = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorTargetName); break; case JsonConstants.ODataErrorDetailsName: error.Details = this.ReadDetails(); break; case JsonConstants.ODataErrorInnerErrorName: error.InnerError = this.ReadInnerError(0 /* recursionDepth */); break; default: // See if it's an instance annotation if (ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName)) { ODataJsonLightPropertyAndValueDeserializer valueDeserializer = new ODataJsonLightPropertyAndValueDeserializer(this.JsonLightInputContext); object typeName = null; var odataAnnotations = duplicationPropertyNameChecker.GetODataPropertyAnnotations(propertyName); if (odataAnnotations != null) { odataAnnotations.TryGetValue(ODataAnnotationNames.ODataType, out typeName); } var value = valueDeserializer.ReadNonEntityValue( typeName as string, null /*expectedValueTypeReference*/, null /*duplicatePropertiesNamesChecker*/, null /*collectionValidator*/, false /*validateNullValue*/, false /*isTopLevelPropertyValue*/, false /*insideComplexValue*/, propertyName); error.GetInstanceAnnotations().Add(new ODataInstanceAnnotation(propertyName, value.ToODataValue())); } else { // we only allow a 'code', 'message', 'target', 'details, and 'innererror' properties // in the value of the 'error' property or custom instance annotations throw new ODataException(Strings.ODataJsonLightErrorDeserializer_TopLevelErrorValueWithInvalidProperty(propertyName)); } break; } }
public void AnnotationsForPropertyShouldBeStored() { DuplicatePropertyNamesChecker duplicateChecker = new DuplicatePropertyNamesChecker(false, true); duplicateChecker.AddODataPropertyAnnotation("property", JsonLightConstants.ODataAnnotationNamespacePrefix + "one", 1); duplicateChecker.AddODataPropertyAnnotation("property", JsonLightConstants.ODataAnnotationNamespacePrefix + "two", "Two"); duplicateChecker.GetODataPropertyAnnotations("property").Should().Equal(new Dictionary<string, object>() { { JsonLightConstants.ODataAnnotationNamespacePrefix + "one", 1 }, { JsonLightConstants.ODataAnnotationNamespacePrefix + "two", "Two" } }); }
public void AnnotationsForPropertyShouldBeStored() { DuplicatePropertyNamesChecker duplicateChecker = new DuplicatePropertyNamesChecker(false, true); duplicateChecker.AddODataPropertyAnnotation("property", JsonLightConstants.ODataAnnotationNamespacePrefix + "one", 1); duplicateChecker.AddODataPropertyAnnotation("property", JsonLightConstants.ODataAnnotationNamespacePrefix + "two", "Two"); duplicateChecker.GetODataPropertyAnnotations("property").Should().Equal(new Dictionary <string, object>() { { JsonLightConstants.ODataAnnotationNamespacePrefix + "one", 1 }, { JsonLightConstants.ODataAnnotationNamespacePrefix + "two", "Two" } }); }
public void NoAnnotationsForPropertyAddedShouldReturnNull() { DuplicatePropertyNamesChecker duplicateChecker = new DuplicatePropertyNamesChecker(false, true); duplicateChecker.GetODataPropertyAnnotations("property").Should().BeNull(); }
public void NoAnnotationsForObjectScopeAddedShouldReturnNull() { DuplicatePropertyNamesChecker duplicateChecker = new DuplicatePropertyNamesChecker(false, true); duplicateChecker.GetODataPropertyAnnotations(string.Empty).Should().BeNull(); }
/// <summary> /// Gets and validates the type name annotation for the specified property. /// </summary> /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker in use for the entry content.</param> /// <param name="propertyName">The name of the property to get the type name for.</param> /// <returns>The type name for the property or null if no type name was found.</returns> protected static string ValidateDataPropertyTypeNameAnnotation(DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, string propertyName) { Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null"); Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); Dictionary<string, object> propertyAnnotations = duplicatePropertyNamesChecker.GetODataPropertyAnnotations(propertyName); string propertyTypeName = null; if (propertyAnnotations != null) { foreach (KeyValuePair<string, object> propertyAnnotation in propertyAnnotations) { if (string.CompareOrdinal(propertyAnnotation.Key, ODataAnnotationNames.ODataType) != 0) { throw new ODataException(ODataErrorStrings.ODataJsonLightPropertyAndValueDeserializer_UnexpectedDataPropertyAnnotation(propertyName, propertyAnnotation.Key)); } Debug.Assert(propertyAnnotation.Value is string && propertyAnnotation.Value != null, "The odata.type annotation should have been parsed as a non-null string."); propertyTypeName = (string)propertyAnnotation.Value; } } return propertyTypeName; }
/// <summary> /// Reads the value of the instance annotation. /// </summary> /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker instance.</param> /// <param name="name">The name of the instance annotation.</param> /// <returns>Returns the value of the instance annotation.</returns> internal object ReadCustomInstanceAnnotationValue(DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, string name) { Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null"); Debug.Assert(!string.IsNullOrEmpty(name), "!string.IsNullOrEmpty(name)"); var propertyAnnotations = duplicatePropertyNamesChecker.GetODataPropertyAnnotations(name); object propertyAnnotation; string odataType = null; if (propertyAnnotations != null && propertyAnnotations.TryGetValue(ODataAnnotationNames.ODataType, out propertyAnnotation)) { odataType = ReaderUtils.AddEdmPrefixOfTypeName(ReaderUtils.RemovePrefixOfTypeName((string)propertyAnnotation)); } // If this term is defined in the model, look up its type. If the term is not in the model, this will be null. IEdmTypeReference expectedTypeFromTerm = MetadataUtils.LookupTypeOfValueTerm(name, this.Model); object customInstanceAnnotationValue = this.ReadNonEntityValueImplementation( odataType, expectedTypeFromTerm, null, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ false, /*validateNullValue*/ false, /*isTopLevelPropertyValue*/ false, /*insideComplexValue Always pass false here to try read @odata.type annotation in custom instance annotations*/ name); return customInstanceAnnotationValue; }
/// <summary> /// Reads an annotation group declaration and returns a newly created annotation group instance. /// </summary> /// <param name="readPropertyAnnotationValue">Function which takes the name of an OData property annotation and reads and returns the value of the annotation.</param> /// <param name="readInstanceAnnotationValue">Function which takes the name of an OData instance annotation and reads and returns the value of the annotation.</param> /// <returns>The annotation group which was read.</returns> /// <remarks> /// Pre-Condition: JsonNodeType.StartObject: The property to consider as an annotion group declaration or reference. /// Any: Any other node type will throw an exception. /// Post-Condition: Any: The node after the annotation group property value. /// </remarks> private ODataJsonLightAnnotationGroup ReadAnnotationGroupDeclaration(Func <string, object> readPropertyAnnotationValue, Func <string, DuplicatePropertyNamesChecker, object> readInstanceAnnotationValue) { ODataJsonLightAnnotationGroup annotationGroup = new ODataJsonLightAnnotationGroup { Annotations = new Dictionary <string, object>(EqualityComparer <string> .Default) }; this.JsonReader.ReadStartObject(); DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker(); while (this.JsonReader.NodeType == JsonNodeType.Property) { this.ProcessProperty( duplicatePropertyNamesChecker, readPropertyAnnotationValue, (propertyParsingResult, propertyName) => { switch (propertyParsingResult) { case PropertyParsingResult.PropertyWithValue: VerifyDataPropertyIsAnnotationName(propertyName, annotationGroup); VerifyAnnotationGroupNameNotYetFound(annotationGroup); annotationGroup.Name = this.JsonReader.ReadStringValue(propertyName); break; case PropertyParsingResult.PropertyWithoutValue: Dictionary <string, object> propertyAnnotations = duplicatePropertyNamesChecker.GetODataPropertyAnnotations(propertyName); if (propertyAnnotations != null) { foreach (KeyValuePair <string, object> propertyAnnotation in propertyAnnotations) { annotationGroup.Annotations.Add(propertyName + JsonLightConstants.ODataPropertyAnnotationSeparatorChar + propertyAnnotation.Key, propertyAnnotation.Value); } } break; case PropertyParsingResult.ODataInstanceAnnotation: annotationGroup.Annotations.Add(propertyName, readInstanceAnnotationValue(propertyName, duplicatePropertyNamesChecker)); break; case PropertyParsingResult.CustomInstanceAnnotation: this.JsonReader.SkipValue(); break; case PropertyParsingResult.MetadataReferenceProperty: throw CreateExceptionForInvalidAnnotationInsideAnnotationGroup(propertyName, annotationGroup); case PropertyParsingResult.EndOfObject: break; default: throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataJsonLightAnnotationGroupDeserializer_ReadAnnotationGroupDeclaration)); } }); } VerifyAnnotationGroupNameFound(annotationGroup); this.JsonReader.ReadEndObject(); this.AddAnnotationGroup(annotationGroup); return(annotationGroup); }