Example #1
0
        /// <summary>
        /// Write an error message.
        /// </summary>
        /// <param name="jsonWriter">The JSON writer to write the error.</param>
        /// <param name="writeInstanceAnnotationsDelegate">Action to write the instance annotations.</param>
        /// <param name="error">The error instance to write.</param>
        /// <param name="includeDebugInformation">A flag indicating whether error details should be written (in debug mode only) or not.</param>
        /// <param name="maxInnerErrorDepth">The maximum number of nested inner errors to allow.</param>
        /// <param name="writingJsonLight">true if we're writing JSON lite, false if we're writing verbose JSON.</param>
        internal static void WriteError(
            IJsonWriter jsonWriter,
            Action <ICollection <ODataInstanceAnnotation> > writeInstanceAnnotationsDelegate,
            ODataError error,
            bool includeDebugInformation,
            int maxInnerErrorDepth,
            bool writingJsonLight)
        {
            Debug.Assert(jsonWriter != null, "jsonWriter != null");
            Debug.Assert(error != null, "error != null");

            string code, message;

            ErrorUtils.GetErrorDetails(error, out code, out message);

            ODataInnerError innerError = includeDebugInformation ? error.InnerError : null;

            WriteError(
                jsonWriter,
                code,
                message,
                error.Target,
                error.Details,
                innerError,
                error.GetInstanceAnnotations(),
                writeInstanceAnnotationsDelegate,
                maxInnerErrorDepth,
                writingJsonLight);
        }
Example #2
0
        /// <summary>
        /// Asynchronously writes an error message.
        /// </summary>
        /// <param name="jsonWriter">The JSON writer to write the error.</param>
        /// <param name="writeInstanceAnnotationsDelegate">Delegate to write the instance annotations.</param>
        /// <param name="error">The error instance to write.</param>
        /// <param name="includeDebugInformation">A flag indicating whether error details should be written (in debug mode only) or not.</param>
        /// <param name="maxInnerErrorDepth">The maximum number of nested inner errors to allow.</param>
        /// <returns>A task that represents the asynchronous write operation.</returns>
        internal static Task WriteErrorAsync(
            IJsonWriterAsync jsonWriter,
            Func <ICollection <ODataInstanceAnnotation>, Task> writeInstanceAnnotationsDelegate,
            ODataError error,
            bool includeDebugInformation,
            int maxInnerErrorDepth)
        {
            Debug.Assert(jsonWriter != null, "jsonWriter != null");
            Debug.Assert(error != null, "error != null");

            ExceptionUtils.CheckArgumentNotNull(writeInstanceAnnotationsDelegate, "writeInstanceAnnotationsDelegate");

            string code, message;

            ErrorUtils.GetErrorDetails(error, out code, out message);

            ODataInnerError innerError = includeDebugInformation ? error.InnerError : null;

            return(WriteErrorAsync(
                       jsonWriter,
                       code,
                       message,
                       error.Target,
                       error.Details,
                       innerError,
                       error.GetInstanceAnnotations(),
                       writeInstanceAnnotationsDelegate,
                       maxInnerErrorDepth));
        }
        /// <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;
            }
        }
Example #4
0
        /// <summary>
        /// Write an error message.
        /// </summary>
        /// <param name="jsonWriter">The JSON writer to write the error.</param>
        /// <param name="writeInstanceAnnotationsDelegate">Action to write the instance annotations.</param>
        /// <param name="error">The error instance to write.</param>
        /// <param name="includeDebugInformation">A flag indicating whether error details should be written (in debug mode only) or not.</param>
        /// <param name="maxInnerErrorDepth">The maximum number of nested inner errors to allow.</param>
        /// <param name="writingJsonLight">true if we're writing JSON lite, false if we're writing verbose JSON.</param>
        internal static void WriteError(IJsonWriter jsonWriter, Action<IEnumerable<ODataInstanceAnnotation>> writeInstanceAnnotationsDelegate, ODataError error, bool includeDebugInformation, int maxInnerErrorDepth, bool writingJsonLight)
        {
            Debug.Assert(jsonWriter != null, "jsonWriter != null");
            Debug.Assert(error != null, "error != null");

            string code, message;
            ErrorUtils.GetErrorDetails(error, out code, out message);

            ODataInnerError innerError = includeDebugInformation ? error.InnerError : null;

            WriteError(jsonWriter, code, message, innerError, error.GetInstanceAnnotations(), writeInstanceAnnotationsDelegate, maxInnerErrorDepth, writingJsonLight);
        }
        /// <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;
            }
        }
        /// <summary>
        /// Asynchronously 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"><see cref="PropertyAndAnnotationCollector"/> to use for extracting property annotations
        /// targeting any custom instance annotations on the error.</param>
        /// <returns>A task that represents the asynchronous read operation.</returns>
        /// <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 async Task ReadPropertyValueInODataErrorObjectAsync(ODataError error, string propertyName, PropertyAndAnnotationCollector duplicationPropertyNameChecker)
        {
            switch (propertyName)
            {
            case JsonConstants.ODataErrorCodeName:
                error.ErrorCode = await this.JsonReader.ReadStringValueAsync(JsonConstants.ODataErrorCodeName)
                                  .ConfigureAwait(false);

                break;

            case JsonConstants.ODataErrorMessageName:
                error.Message = await this.JsonReader.ReadStringValueAsync(JsonConstants.ODataErrorMessageName)
                                .ConfigureAwait(false);

                break;

            case JsonConstants.ODataErrorTargetName:
                error.Target = await this.JsonReader.ReadStringValueAsync(JsonConstants.ODataErrorTargetName)
                               .ConfigureAwait(false);

                break;

            case JsonConstants.ODataErrorDetailsName:
                error.Details = await this.ReadErrorDetailsAsync()
                                .ConfigureAwait(false);

                break;

            case JsonConstants.ODataErrorInnerErrorName:
                error.InnerError = await this.ReadInnerErrorAsync(recursionDepth : 0)
                                   .ConfigureAwait(false);

                break;

            default:
                // See if it's an instance annotation
                if (ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName))
                {
                    ODataJsonLightPropertyAndValueDeserializer propertyAndValueDeserializer = new ODataJsonLightPropertyAndValueDeserializer(this.JsonLightInputContext);
                    object typeName;

                    duplicationPropertyNameChecker.GetODataPropertyAnnotations(propertyName).TryGetValue(ODataAnnotationNames.ODataType, out typeName);

                    var value = await propertyAndValueDeserializer.ReadNonEntityValueAsync(
                        payloadTypeName : typeName as string,
                        expectedValueTypeReference : null,
                        propertyAndAnnotationCollector : null,
                        collectionValidator : null,
                        validateNullValue : false,
                        isTopLevelPropertyValue : false,
                        insideResourceValue : false,
                        propertyName : propertyName).ConfigureAwait(false);

                    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;
            }
        }