示例#1
0
        /// <summary>
        /// Adds an OData annotation to a property.
        /// </summary>
        /// <param name="propertyName">The name of the property to add annotation to. string.empty means the annotation is for the current scope.</param>
        /// <param name="annotationName">The name of the annotation to add.</param>
        /// <param name="annotationValue">The valud of the annotation to add.</param>
        internal void AddODataPropertyAnnotation(string propertyName, string annotationName, object annotationValue)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");
            Debug.Assert(!string.IsNullOrEmpty(annotationName), "!string.IsNullOrEmpty(annotationName)");
            Debug.Assert(JsonLight.ODataJsonLightReaderUtils.IsODataAnnotationName(annotationName), "annotationName must be an OData annotation.");

            DuplicationRecord           duplicationRecord = this.GetDuplicationRecordToAddPropertyAnnotation(propertyName, annotationName);
            Dictionary <string, object> odataAnnotations  = duplicationRecord.PropertyODataAnnotations;

            if (odataAnnotations == null)
            {
                odataAnnotations = new Dictionary <string, object>(StringComparer.Ordinal);
                duplicationRecord.PropertyODataAnnotations = odataAnnotations;
            }
            else if (odataAnnotations.ContainsKey(annotationName))
            {
                if (ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName))
                {
                    throw new ODataException(Strings.DuplicatePropertyNamesChecker_DuplicateAnnotationForInstanceAnnotationNotAllowed(annotationName, propertyName));
                }

                throw new ODataException(Strings.DuplicatePropertyNamesChecker_DuplicateAnnotationForPropertyNotAllowed(annotationName, propertyName));
            }

            odataAnnotations.Add(annotationName, annotationValue);
        }
示例#2
0
        /// <summary>
        /// Throw if property is processed already.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="duplicationRecord">DuplicationRecord of the property.</param>
        private static void ThrowIfPropertyIsProcessed(string propertyName, DuplicationRecord duplicationRecord)
        {
            if (object.ReferenceEquals(duplicationRecord.PropertyODataAnnotations, propertyAnnotationsProcessedToken))
            {
                if (ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName) && !ODataJsonLightUtils.IsMetadataReferenceProperty(propertyName))
                {
                    throw new ODataException(Strings.DuplicatePropertyNamesChecker_DuplicateAnnotationNotAllowed(propertyName));
                }

                throw new ODataException(Strings.DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed(propertyName));
            }
        }
示例#3
0
        /// <summary>
        /// Marks a property to note that all its annotations should have been processed by now.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        /// <remarks>
        /// It's an error if more annotations for a marked property are found later in the payload.
        /// </remarks>
        internal void MarkPropertyAsProcessed(string propertyName)
        {
            Debug.Assert(propertyName != null);

            PropertyData data;

            if (!propertyData.TryGetValue(propertyName, out data))
            {
                propertyData[propertyName] = data = new PropertyData(PropertyState.AnnotationSeen);
            }

            if (data.Processed)
            {
                throw new ODataException(
                          ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName) &&
                          !ODataJsonLightUtils.IsMetadataReferenceProperty(propertyName)
                    ? Strings.DuplicateAnnotationNotAllowed(propertyName)
                    : Strings.DuplicatePropertyNamesNotAllowed(propertyName));
            }

            data.Processed = true;
        }
示例#4
0
        /// <summary>
        /// Adds an OData property annotation.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="annotationName">Name of the annotation.</param>
        /// <param name="annotationValue">Value of the annotation.</param>
        internal void AddODataPropertyAnnotation(string propertyName, string annotationName, object annotationValue)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName));
            Debug.Assert(!string.IsNullOrEmpty(annotationName));
            Debug.Assert(JsonLight.ODataJsonLightReaderUtils.IsODataAnnotationName(annotationName));

            if (annotationValue == null)
            {
                return;
            }

            PropertyData data;

            if (!propertyData.TryGetValue(propertyName, out data))
            {
                propertyData[propertyName] = data = new PropertyData(PropertyState.AnnotationSeen);
            }
            else
            {
                if (data.Processed)
                {
                    throw new ODataException(
                              Strings.PropertyAnnotationAfterTheProperty(
                                  annotationName, propertyName));
                }
            }

            try
            {
                data.ODataAnnotations.Add(annotationName, annotationValue);
            }
            catch (ArgumentException)
            {
                throw new ODataException(
                          ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName)
                    ? Strings.DuplicateAnnotationForInstanceAnnotationNotAllowed(annotationName, propertyName)
                    : Strings.DuplicateAnnotationForPropertyNotAllowed(annotationName, propertyName));
            }
        }
示例#5
0
        /// <summary>
        /// Try to read an inner error property value.
        /// </summary>
        /// <param name="innerError">An <see cref="ODataInnerError"/> instance that was read from the reader or null if none could be read.</param>
        /// <param name="recursionDepth">The number of times this method has been called recursively.</param>
        /// <returns>true if an <see cref="ODataInnerError"/> instance that was read; otherwise false.</returns>
        private bool TryReadInnerErrorPropertyValue(out ODataInnerError innerError, int recursionDepth)
        {
            Debug.Assert(this.currentBufferedNode.NodeType == JsonNodeType.Property, "this.currentBufferedNode.NodeType == JsonNodeType.Property");
            Debug.Assert(this.parsingInStreamError, "this.parsingInStreamError");
            this.AssertBuffering();

            ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, this.maxInnerErrorDepth);

            // move the reader onto the property value
            this.ReadInternal();

            // we expect a start-object node here
            if (this.currentBufferedNode.NodeType != JsonNodeType.StartObject)
            {
                innerError = null;
                return(false);
            }

            // read the start-object node
            this.ReadInternal();

            innerError = new ODataInnerError();

            // we expect one of the supported properties for the value (or end-object)
            ODataJsonLightReaderUtils.ErrorPropertyBitMask propertiesFoundBitmask = ODataJsonLightReaderUtils.ErrorPropertyBitMask.None;
            while (this.currentBufferedNode.NodeType == JsonNodeType.Property)
            {
                // NOTE the Json reader already ensures that the value of a property node is a string
                string propertyName = (string)this.currentBufferedNode.Value;

                switch (propertyName)
                {
                case JsonConstants.ODataErrorInnerErrorMessageName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.MessageValue))
                    {
                        return(false);
                    }

                    string message;
                    if (this.TryReadErrorStringPropertyValue(out message))
                    {
                        innerError.Message = message;
                    }
                    else
                    {
                        return(false);
                    }

                    break;

                case JsonConstants.ODataErrorInnerErrorTypeNameName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.TypeName))
                    {
                        return(false);
                    }

                    string typeName;
                    if (this.TryReadErrorStringPropertyValue(out typeName))
                    {
                        innerError.TypeName = typeName;
                    }
                    else
                    {
                        return(false);
                    }

                    break;

                case JsonConstants.ODataErrorInnerErrorStackTraceName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.StackTrace))
                    {
                        return(false);
                    }

                    string stackTrace;
                    if (this.TryReadErrorStringPropertyValue(out stackTrace))
                    {
                        innerError.StackTrace = stackTrace;
                    }
                    else
                    {
                        return(false);
                    }

                    break;

                case JsonConstants.ODataErrorInnerErrorInnerErrorName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.InnerError))
                    {
                        return(false);
                    }

                    ODataInnerError nestedInnerError;
                    if (this.TryReadInnerErrorPropertyValue(out nestedInnerError, recursionDepth))
                    {
                        innerError.InnerError = nestedInnerError;
                    }
                    else
                    {
                        return(false);
                    }

                    break;

                default:
                    // if we find a non-supported property in an inner error, we skip it
                    this.SkipValueInternal();
                    break;
                }

                this.ReadInternal();
            }

            Debug.Assert(this.currentBufferedNode.NodeType == JsonNodeType.EndObject, "this.currentBufferedNode.NodeType == JsonNodeType.EndObject");

            return(true);
        }
示例#6
0
        private bool TryReadErrorDetail(out ODataErrorDetail detail)
        {
            Debug.Assert(
                this.currentBufferedNode.NodeType == JsonNodeType.StartObject,
                "this.currentBufferedNode.NodeType == JsonNodeType.StartObject");
            Debug.Assert(this.parsingInStreamError, "this.parsingInStreamError");
            this.AssertBuffering();

            if (this.currentBufferedNode.NodeType != JsonNodeType.StartObject)
            {
                detail = null;
                return(false);
            }

            // {
            ReadInternal();

            detail = new ODataErrorDetail();

            // we expect one of the supported properties for the value (or end-object)
            var propertiesFoundBitmask = ODataJsonLightReaderUtils.ErrorPropertyBitMask.None;

            while (this.currentBufferedNode.NodeType == JsonNodeType.Property)
            {
                var propertyName = (string)this.currentBufferedNode.Value;

                switch (propertyName)
                {
                case JsonConstants.ODataErrorCodeName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(
                            ref propertiesFoundBitmask,
                            ODataJsonLightReaderUtils.ErrorPropertyBitMask.Code))
                    {
                        return(false);
                    }

                    string code;
                    if (this.TryReadErrorStringPropertyValue(out code))
                    {
                        detail.ErrorCode = code;
                    }
                    else
                    {
                        return(false);
                    }

                    break;

                case JsonConstants.ODataErrorTargetName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(
                            ref propertiesFoundBitmask,
                            ODataJsonLightReaderUtils.ErrorPropertyBitMask.Target))
                    {
                        return(false);
                    }

                    string target;
                    if (this.TryReadErrorStringPropertyValue(out target))
                    {
                        detail.Target = target;
                    }
                    else
                    {
                        return(false);
                    }

                    break;

                case JsonConstants.ODataErrorMessageName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(
                            ref propertiesFoundBitmask,
                            ODataJsonLightReaderUtils.ErrorPropertyBitMask.MessageValue))
                    {
                        return(false);
                    }

                    string message;
                    if (this.TryReadErrorStringPropertyValue(out message))
                    {
                        detail.Message = message;
                    }
                    else
                    {
                        return(false);
                    }

                    break;

                default:
                    // if we find a non-supported property in an inner error, we skip it
                    this.SkipValueInternal();
                    break;
                }

                this.ReadInternal();
            }

            Debug.Assert(
                this.currentBufferedNode.NodeType == JsonNodeType.EndObject,
                "this.currentBufferedNode.NodeType == JsonNodeType.EndObject");

            return(true);
        }
示例#7
0
        /// <summary>
        /// Try to read an error structure from the stream. Return null if no error structure can be read.
        /// </summary>
        /// <param name="error">An <see cref="ODataError"/> instance that was read from the reader or null if none could be read.</param>
        /// <returns>true if an <see cref="ODataError"/> instance that was read; otherwise false.</returns>
        private bool TryReadInStreamErrorPropertyValue(out ODataError error)
        {
            Debug.Assert(this.parsingInStreamError, "this.parsingInStreamError");
            this.AssertBuffering();

            error = null;

            // we expect a start-object node here
            if (this.currentBufferedNode.NodeType != JsonNodeType.StartObject)
            {
                return(false);
            }

            // read the start-object node
            this.ReadInternal();

            error = new ODataError();

            // we expect one of the supported properties for the value (or end-object)
            ODataJsonLightReaderUtils.ErrorPropertyBitMask propertiesFoundBitmask = ODataJsonLightReaderUtils.ErrorPropertyBitMask.None;
            while (this.currentBufferedNode.NodeType == JsonNodeType.Property)
            {
                // NOTE the Json reader already ensures that the value of a property node is a string
                string propertyName = (string)this.currentBufferedNode.Value;
                switch (propertyName)
                {
                case JsonConstants.ODataErrorCodeName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.Code))
                    {
                        return(false);
                    }

                    string errorCode;
                    if (this.TryReadErrorStringPropertyValue(out errorCode))
                    {
                        error.ErrorCode = errorCode;
                    }
                    else
                    {
                        return(false);
                    }

                    break;

                case JsonConstants.ODataErrorMessageName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.Message))
                    {
                        return(false);
                    }

                    string errorMessage;
                    if (this.TryReadErrorStringPropertyValue(out errorMessage))
                    {
                        error.Message = errorMessage;
                    }
                    else
                    {
                        return(false);
                    }

                    break;

                case JsonConstants.ODataErrorTargetName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(
                            ref propertiesFoundBitmask,
                            ODataJsonLightReaderUtils.ErrorPropertyBitMask.Target))
                    {
                        return(false);
                    }

                    string errorTarget;
                    if (this.TryReadErrorStringPropertyValue(out errorTarget))
                    {
                        error.Target = errorTarget;
                    }
                    else
                    {
                        return(false);
                    }

                    break;

                case JsonConstants.ODataErrorDetailsName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(
                            ref propertiesFoundBitmask,
                            ODataJsonLightReaderUtils.ErrorPropertyBitMask.Details))
                    {
                        return(false);
                    }

                    ICollection <ODataErrorDetail> details;
                    if (!this.TryReadErrorDetailsPropertyValue(out details))
                    {
                        return(false);
                    }

                    error.Details = details;
                    break;

                case JsonConstants.ODataErrorInnerErrorName:
                    if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.InnerError))
                    {
                        return(false);
                    }

                    ODataInnerError innerError;
                    if (!this.TryReadInnerErrorPropertyValue(out innerError, 0 /*recursionDepth */))
                    {
                        return(false);
                    }

                    error.InnerError = innerError;
                    break;

                default:
                    // if we find a non-supported property we don't treat this as an error
                    return(false);
                }

                this.ReadInternal();
            }

            // read the end object
            Debug.Assert(this.currentBufferedNode.NodeType == JsonNodeType.EndObject, "this.currentBufferedNode.NodeType == JsonNodeType.EndObject");
            this.ReadInternal();

            // if we don't find any properties it is not a valid error object
            return(propertiesFoundBitmask != ODataJsonLightReaderUtils.ErrorPropertyBitMask.None);
        }