Example #1
0
        /// <summary>
        /// Converts a <see cref="ODataCollectionValue"/> to a string for use in a Url.
        /// </summary>
        /// <param name="collectionValue">Instance to convert.</param>
        /// <param name="model">Model to be used for validation. User model is optional. The EdmLib core model is expected as a minimum.</param>
        /// <param name="version">Version to be compliant with. Collection requires >= V3.</param>
        /// <param name="format">ODataFormat to use for the format of the literal.</param>
        /// <returns>A string representation of <paramref name="collectionValue"/> to be added to a Url.</returns>
        internal static string ConvertToUriCollectionLiteral(ODataCollectionValue collectionValue, IEdmModel model, ODataVersion version, ODataFormat format)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(collectionValue, "collectionValue");
            ExceptionUtils.CheckArgumentNotNull(model, "model");

            ODataVersionChecker.CheckCollectionValue(version);

            StringBuilder builder = new StringBuilder();

            using (TextWriter textWriter = new StringWriter(builder, CultureInfo.InvariantCulture))
            {
                ODataMessageWriterSettings messageWriterSettings = new ODataMessageWriterSettings()
                {
                    Version = version,
                    Indent  = false
                };

                if (format == ODataFormat.VerboseJson)
                {
                    WriteJsonVerboseLiteral(
                        model,
                        messageWriterSettings,
                        textWriter,
                        (serializer) => serializer.WriteCollectionValue(
                            collectionValue,
                            null /*metadataTypeReference*/,
                            false /*isOpenPropertyType*/));
                }
                else if (format == ODataFormat.Json)
                {
                    WriteJsonLightLiteral(
                        model,
                        messageWriterSettings,
                        textWriter,
                        (serializer) => serializer.WriteCollectionValue(
                            collectionValue,
                            null /*metadataTypeReference*/,
                            false /*isTopLevelProperty*/,
                            true /*isInUri*/,
                            false /*isOpenPropertyType*/));
                }
                else
                {
                    throw new ArgumentException(ODataErrorStrings.ODataUriUtils_ConvertToUriLiteralUnsupportedFormat(format.ToString()));
                }
            }

            return(builder.ToString());
        }
 internal static string ConvertToUriCollectionLiteral(ODataCollectionValue collectionValue, IEdmModel model, ODataVersion version)
 {
     ExceptionUtils.CheckArgumentNotNull<ODataCollectionValue>(collectionValue, "collectionValue");
     ExceptionUtils.CheckArgumentNotNull<IEdmModel>(model, "model");
     ODataVersionChecker.CheckCollectionValue(version);
     StringBuilder sb = new StringBuilder();
     using (TextWriter writer = new StringWriter(sb, CultureInfo.InvariantCulture))
     {
         JsonWriter jsonWriter = new JsonWriter(writer, false);
         ODataMessageWriterSettings messageWriterSettings = new ODataMessageWriterSettings {
             Version = new ODataVersion?(version)
         };
         using (ODataJsonOutputContext context = ODataJsonOutputContext.Create(ODataFormat.VerboseJson, jsonWriter, messageWriterSettings, false, model, null))
         {
             new ODataJsonPropertyAndValueSerializer(context).WriteCollectionValue(collectionValue, null, false);
         }
     }
     return sb.ToString();
 }
Example #3
0
        /// <summary>
        /// Converts a <see cref="ODataCollectionValue"/> to a string for use in a Url.
        /// </summary>
        /// <param name="collectionValue">Instance to convert.</param>
        /// <param name="model">Model to be used for validation. User model is optional. The EdmLib core model is expected as a minimum.</param>
        /// <param name="version">Version to be compliant with. Collection requires >= V3.</param>
        /// <returns>A string representation of <paramref name="collectionValue"/> to be added to a Url.</returns>
        internal static string ConvertToUriCollectionLiteral(ODataCollectionValue collectionValue, IEdmModel model, ODataVersion version)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(collectionValue, "collectionValue");
            ExceptionUtils.CheckArgumentNotNull(model, "model");

            ODataVersionChecker.CheckCollectionValue(version);

            StringBuilder builder = new StringBuilder();

            using (TextWriter textWriter = new StringWriter(builder, CultureInfo.InvariantCulture))
            {
                JsonWriter jsonWriter = new JsonWriter(textWriter, false);
                ODataMessageWriterSettings messageWriterSettings = new ODataMessageWriterSettings()
                {
                    Version = version
                };

                // Calling dispose since it's the right thing to do, but when created from JsonWriter
                // the output context Dispose will not actually dispose anything, it will just cleanup itself.
                using (ODataJsonOutputContext jsonOutputContext = ODataJsonOutputContext.Create(
                           ODataFormat.VerboseJson,
                           jsonWriter,
                           messageWriterSettings,
                           false /*writingResponse*/,
                           model,
                           null /*urlResolver*/))
                {
                    ODataJsonPropertyAndValueSerializer jsonPropertyAndValueSerializer = new ODataJsonPropertyAndValueSerializer(jsonOutputContext);

                    jsonPropertyAndValueSerializer.WriteCollectionValue(
                        collectionValue,
                        null, /*propertyTypeRefereence*/
                        false /*openPropertyType - this determines if the TypeName will be written*/);
                    jsonPropertyAndValueSerializer.AssertRecursionDepthIsZero();
                }
            }

            return(builder.ToString());
        }
Example #4
0
        /// <summary>
        /// Reads a collection value.
        /// </summary>
        /// <param name="collectionValueTypeReference">The collection type reference of the value.</param>
        /// <param name="payloadTypeName">The type name read from the payload.</param>
        /// <param name="serializationTypeNameAnnotation">The serialization type name for the collection value (possibly null).</param>
        /// <returns>The value of the collection.</returns>
        /// <remarks>
        /// Pre-Condition:  Fails if the current node is not a JsonNodeType.StartObject
        /// Post-Condition: almost anything - the node after the collection value (after the EndObject)
        /// </remarks>
        private ODataCollectionValue ReadCollectionValueImplementation(
            IEdmCollectionTypeReference collectionValueTypeReference,
            string payloadTypeName,
            SerializationTypeNameAnnotation serializationTypeNameAnnotation)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(
                collectionValueTypeReference == null || collectionValueTypeReference.IsNonEntityCollectionType(),
                "If the metadata is specified it must denote a Collection for this method to work.");
            this.JsonReader.AssertNotBuffering();

            ODataVersionChecker.CheckCollectionValue(this.Version);

            this.IncreaseRecursionDepth();

            // Read over the start object
            this.JsonReader.ReadStartObject();

            ODataCollectionValue collectionValue = new ODataCollectionValue();

            collectionValue.TypeName = collectionValueTypeReference != null?collectionValueTypeReference.ODataFullName() : payloadTypeName;

            if (serializationTypeNameAnnotation != null)
            {
                collectionValue.SetAnnotation(serializationTypeNameAnnotation);
            }

            List <object> items = null;
            bool          metadataPropertyFound = false;

            while (this.JsonReader.NodeType == JsonNodeType.Property)
            {
                string propertyName = this.JsonReader.ReadPropertyName();

                if (string.CompareOrdinal(JsonConstants.ODataMetadataName, propertyName) == 0)
                {
                    // __metadata property
                    if (metadataPropertyFound)
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonPropertyAndValueDeserializer_MultiplePropertiesInCollectionWrapper(JsonConstants.ODataMetadataName));
                    }

                    metadataPropertyFound = true;

                    // Note that we don't need to read the type name again, as we've already read it above in FindTypeNameInPayload.
                    // There's nothing else of interest in the __metadata for collections.
                    this.JsonReader.SkipValue();
                }
                else if (string.CompareOrdinal(JsonConstants.ODataResultsName, propertyName) == 0)
                {
                    // results property
                    if (items != null)
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonPropertyAndValueDeserializer_MultiplePropertiesInCollectionWrapper(JsonConstants.ODataResultsName));
                    }

                    items = new List <object>();

                    this.JsonReader.ReadStartArray();

                    DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker();
                    IEdmTypeReference             itemType = null;
                    if (collectionValueTypeReference != null)
                    {
                        itemType = collectionValueTypeReference.CollectionDefinition().ElementType;
                    }

                    // NOTE: we do not support reading Verbose JSON without metadata right now so we always have an expected item type;
                    //       The collection validator is always null.
                    CollectionWithoutExpectedTypeValidator collectionValidator = null;

                    while (this.JsonReader.NodeType != JsonNodeType.EndArray)
                    {
                        object itemValue = this.ReadNonEntityValueImplementation(
                            itemType,
                            duplicatePropertyNamesChecker,
                            collectionValidator,
                            /*validateNullValue*/ true,
                            /*propertyName*/ null);

                        // Validate the item (for example that it's not null)
                        ValidationUtils.ValidateCollectionItem(itemValue, false /* isStreamable */);

                        // Note that the ReadNonEntityValue already validated that the actual type of the value matches
                        // the expected type (the itemType).
                        items.Add(itemValue);
                    }

                    Debug.Assert(this.JsonReader.NodeType == JsonNodeType.EndArray, "The results value must end with an end array.");
                    this.JsonReader.ReadEndArray();
                }
                else
                {
                    // Skip over any other property in the collection object
                    this.JsonReader.SkipValue();
                }
            }

            Debug.Assert(this.JsonReader.NodeType == JsonNodeType.EndObject, "After all properties of Collection wrapper are read the EndObject node is expected.");
            this.JsonReader.ReadEndObject();

            if (items == null)
            {
                // We didn't find any results property. All collections must have the results property.
                throw new ODataException(ODataErrorStrings.ODataJsonPropertyAndValueDeserializer_CollectionWithoutResults);
            }

            collectionValue.Items = new ReadOnlyEnumerable(items);

            this.JsonReader.AssertNotBuffering();
            this.DecreaseRecursionDepth();

            return(collectionValue);
        }
Example #5
0
        private ODataCollectionValue ReadCollectionValueImplementation(IEdmCollectionTypeReference collectionValueTypeReference, string payloadTypeName, SerializationTypeNameAnnotation serializationTypeNameAnnotation)
        {
            ODataVersionChecker.CheckCollectionValue(base.Version);
            this.IncreaseRecursionDepth();
            base.JsonReader.ReadStartObject();
            ODataCollectionValue value2 = new ODataCollectionValue {
                TypeName = (collectionValueTypeReference != null) ? collectionValueTypeReference.ODataFullName() : payloadTypeName
            };

            if (serializationTypeNameAnnotation != null)
            {
                value2.SetAnnotation <SerializationTypeNameAnnotation>(serializationTypeNameAnnotation);
            }
            List <object> sourceEnumerable = null;
            bool          flag             = false;

            while (base.JsonReader.NodeType == JsonNodeType.Property)
            {
                string strB = base.JsonReader.ReadPropertyName();
                if (string.CompareOrdinal("__metadata", strB) == 0)
                {
                    if (flag)
                    {
                        throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonPropertyAndValueDeserializer_MultiplePropertiesInCollectionWrapper("__metadata"));
                    }
                    flag = true;
                    base.JsonReader.SkipValue();
                }
                else
                {
                    if (string.CompareOrdinal("results", strB) == 0)
                    {
                        if (sourceEnumerable != null)
                        {
                            throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonPropertyAndValueDeserializer_MultiplePropertiesInCollectionWrapper("results"));
                        }
                        sourceEnumerable = new List <object>();
                        base.JsonReader.ReadStartArray();
                        DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = base.CreateDuplicatePropertyNamesChecker();
                        IEdmTypeReference             expectedTypeReference         = null;
                        if (collectionValueTypeReference != null)
                        {
                            expectedTypeReference = collectionValueTypeReference.CollectionDefinition().ElementType;
                        }
                        CollectionWithoutExpectedTypeValidator collectionValidator = null;
                        while (base.JsonReader.NodeType != JsonNodeType.EndArray)
                        {
                            object item = this.ReadNonEntityValueImplementation(expectedTypeReference, duplicatePropertyNamesChecker, collectionValidator, true);
                            ValidationUtils.ValidateCollectionItem(item, false);
                            sourceEnumerable.Add(item);
                        }
                        base.JsonReader.ReadEndArray();
                        continue;
                    }
                    base.JsonReader.SkipValue();
                }
            }
            base.JsonReader.ReadEndObject();
            if (sourceEnumerable == null)
            {
                throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonPropertyAndValueDeserializer_CollectionWithoutResults);
            }
            value2.Items = new ReadOnlyEnumerable(sourceEnumerable);
            this.DecreaseRecursionDepth();
            return(value2);
        }