private void RunPropertyParsingTest( string jsonInput, ODataJsonLightDeserializer.PropertyParsingResult expectedPropertyParsingResult, string expectedName, Action<JsonReader, DuplicatePropertyNamesChecker> additionalVerification = null, Func<JsonReader, string, object> readPropertyAnnotationValue = null, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = null) { if (duplicatePropertyNamesChecker == null) { duplicatePropertyNamesChecker = new DuplicatePropertyNamesChecker(false, true); } if (readPropertyAnnotationValue == null) { readPropertyAnnotationValue = (jsonReader, annotationName) => jsonReader.ReadPrimitiveValue(); } using (ODataJsonLightInputContext inputContext = this.CreateJsonLightInputContext(jsonInput)) { ODataJsonLightDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(inputContext); AdvanceReaderToFirstProperty(deserializer.JsonReader); deserializer.ProcessProperty( duplicatePropertyNamesChecker, (propertyName) => readPropertyAnnotationValue(deserializer.JsonReader, propertyName), (propertyParsingResult, propertyName) => { propertyParsingResult.Should().Be(expectedPropertyParsingResult, "parsing JSON object '{0}'", jsonInput); propertyName.Should().Be(expectedName, "reported name is wrong for JSON object '{0}'", jsonInput); if (additionalVerification != null) { additionalVerification(deserializer.JsonReader, duplicatePropertyNamesChecker); } }); } }
/// <summary> /// Detects the payload kind(s). /// </summary> /// <param name="detectionInfo">Additional information available for the payload kind detection.</param> /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns> private IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(ODataPayloadKindDetectionInfo detectionInfo) { Debug.Assert(detectionInfo != null, "detectionInfo != null"); Debug.Assert(this.JsonReader.DisableInStreamErrorDetection, "The in-stream error detection should be disabled for payload kind detection."); this.AssertJsonCondition(JsonNodeType.Property, JsonNodeType.EndObject); // If we found a context URI and parsed it, look at the detected payload kind and return it. if (this.ContextUriParseResult != null) { // Store the parsed context URI on the input context so we can avoid parsing it again. detectionInfo.SetPayloadKindDetectionFormatState(new ODataJsonLightPayloadKindDetectionState(this.ContextUriParseResult)); return(this.ContextUriParseResult.DetectedPayloadKinds); } // Otherwise this is a payload without context URI and we have to start sniffing; only error payloads // don't have a context URI so check for a single 'error' property (ignoring custom annotations). ODataError error = null; while (this.JsonReader.NodeType == JsonNodeType.Property) { string propertyName = this.JsonReader.ReadPropertyName(); string annotatedPropertyName, annotationName; if (!ODataJsonLightDeserializer.TryParsePropertyAnnotation(propertyName, out annotatedPropertyName, out annotationName)) { if (ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName)) { if (propertyName != null && propertyName.StartsWith(JsonLightConstants.ODataPropertyAnnotationSeparatorChar + JsonLightConstants.ODataAnnotationNamespacePrefix, System.StringComparison.Ordinal)) { // Any @odata.* instance annotations are not allowed for errors. return(Enumerable.Empty <ODataPayloadKind>()); } else { // Skip custom instance annotations this.JsonReader.SkipValue(); } } else { if (string.CompareOrdinal(JsonLightConstants.ODataErrorPropertyName, propertyName) == 0) { // If we find multiple errors or an invalid error value, this is not an error payload. if (error != null || !this.JsonReader.StartBufferingAndTryToReadInStreamErrorPropertyValue(out error)) { return(Enumerable.Empty <ODataPayloadKind>()); } // At this point we successfully read the first error property. // Skip the error value and check whether there are more properties. this.JsonReader.SkipValue(); } else { // if it contains non-annotation property, it is not an error payload. return(Enumerable.Empty <ODataPayloadKind>()); } } } else { // Property annotation return(Enumerable.Empty <ODataPayloadKind>()); } } // If we got here without finding a context URI or an error payload, we don't know what this is. if (error == null) { return(Enumerable.Empty <ODataPayloadKind>()); } return(new ODataPayloadKind[] { ODataPayloadKind.Error }); }