コード例 #1
0
        public PropertyInstance MultiValuePropertyEmptyOrNull(MemberProperty memberProperty, object value)
        {
            var bagPropertyType = memberProperty.PropertyType as CollectionDataType;

            ExceptionUtilities.CheckObjectNotNull(bagPropertyType, "Expected property to be a BagProperty instead its a '{0}'", memberProperty.PropertyType);

            DataType elementDataType = bagPropertyType.ElementDataType;

            if (value == null)
            {
                return(new NullPropertyInstance(memberProperty.Name, elementDataType.BuildMultiValueTypeName()));
            }
            else
            {
                ExceptionUtilities.Assert(value == EmptyData.Value, "value MUST be null or EmptyData.Value");
                PropertyInstance collectionProperty = null;
                if (elementDataType is ComplexDataType)
                {
                    collectionProperty = new ComplexMultiValueProperty(memberProperty.Name, new ComplexMultiValue(elementDataType.BuildMultiValueTypeName(), false));
                }
                else
                {
                    ExceptionUtilities.Assert(elementDataType is PrimitiveDataType, "DataType is not a PrimitiveDataType '{0}'", elementDataType);
                    collectionProperty = new PrimitiveMultiValueProperty(memberProperty.Name, new PrimitiveMultiValue(elementDataType.BuildMultiValueTypeName(), false));
                }

                // Add an empty one if specified to
                return(collectionProperty);
            }
        }
コード例 #2
0
        private static ComplexMultiValueProperty GetComplexMultiValueProperty(IRandomNumberGenerator random, EdmModel model = null, ODataVersion version = ODataVersion.V4)
        {
            int numinstances = random.ChooseFrom(new[] { 0, 1, 3 });
            var instance     = GetComplexInstance(random, model, version);
            var instances    = GenerateSimilarComplexInstances(random, instance, numinstances, true);
            var propertyName = "ComplexMultivalue" + instance.FullTypeName;
            var payload      = new ComplexMultiValueProperty(propertyName,
                                                             new ComplexMultiValue(propertyName, false, instances.ToArray()));

            if (model != null)
            {
                var entityDataType = instance.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType.Definition as IEdmEntityType;
                ExceptionUtilities.CheckObjectNotNull(entityDataType, "Complex Instance must have an EntityModelTypeAnnotation with an EntityDataType");
                var entityType = model.FindDeclaredType(entityDataType.FullName()) as EdmEntityType;

                ExceptionUtilities.CheckObjectNotNull(entityType, "entityType");
                if (entityType.FindProperty(propertyName) != null)
                {
                    entityType.AddStructuralProperty(propertyName, (model.FindDeclaredType(instance.FullTypeName) as EdmComplexType).ToTypeReference());
                }

                payload.WithTypeAnnotation(entityType);
            }

            return(payload);
        }
コード例 #3
0
        /// <summary>
        /// Visits a complex property.  A copy of the current properties to be written is taken so that
        /// the complex property can use the global list to track its properties as its children are visited.
        /// Adds the complex property to the list of properties to be written.
        /// </summary>
        /// <param name="payloadElement">The complex property to visit and add</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            // Save off properties of parent
            var arr   = this.odataProperties;
            var items = new List <ODataComplexValue>();

            foreach (var item in payloadElement.Value)
            {
                this.odataProperties = new List <ODataProperty>();

                this.Visit(item);
                ExceptionUtilities.CheckObjectNotNull(this.odataProperties, "ODataProperties cannot be null");
                var typename     = item.FullTypeName.Substring(11, item.FullTypeName.Length - 12);
                var complexValue = new ODataComplexValue()
                {
                    TypeName = typename
                };
                complexValue.Properties = this.odataProperties.ToList();//.AsEnumerable();
                items.Add(complexValue);
            }

            //Return the global property list to its initial state with the new complex property added
            this.odataProperties.Clear();
            this.odataProperties.AddRange(arr);

            //create a new complex collection property to add to the list from the properties children
            this.odataProperties.Add(new ODataProperty()
            {
                Name  = payloadElement.Name,
                Value = new ODataCollectionValue()
                {
                    Items = items, TypeName = payloadElement.Value.FullTypeName
                }
            });
        }
コード例 #4
0
        private void PopulateComplexMultiValuePropertyFromPaths(ComplexInstance instance, MemberProperty memberProperty, string propertyPath, IEnumerable <NamedValue> namedValues, ComplexDataType complexTypeElementDataType)
        {
            int  i         = 0;
            bool completed = false;

            var complexCollection = new ComplexMultiValueProperty(memberProperty.Name, new ComplexMultiValue(complexTypeElementDataType.BuildMultiValueTypeName(), false));

            while (!completed)
            {
                IEnumerable <NamedValue> complexInstanceNamedValues = namedValues.Where(pp => pp.Name.StartsWith(propertyPath + "." + i + ".", StringComparison.Ordinal)).ToList();
                if (complexInstanceNamedValues.Count() == 0)
                {
                    completed = true;
                }
                else
                {
                    ComplexInstance complexInstance = this.ComplexInstance(complexTypeElementDataType.Definition, propertyPath + "." + i, complexInstanceNamedValues);
                    complexCollection.Value.Add(complexInstance);
                }

                i++;
            }

            if (i > 1)
            {
                instance.Add(complexCollection);
            }
        }
コード例 #5
0
        /// <summary>
        /// Visits a ComplexMultiValueProperty, if this is not the result of a service operation call, it will be a V3 payload
        /// </summary>
        /// <param name="payloadElement">payload Element</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");

            this.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4);

            base.Visit(payloadElement);
        }
コード例 #6
0
        /// <summary>
        /// Visits a ComplexMultiValueProperty, if this is not the result of a service operation call, it will be a V3 payload
        /// </summary>
        /// <param name="payloadElement">payload Element</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");

            this.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4);

            base.Visit(payloadElement);
        }
コード例 #7
0
        /// <summary>
        /// Visits the payload element
        /// </summary>
        /// <param name="payloadElement">The payload element to visit</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");

            var annotation = payloadElement.Annotations.Where(a => a is MemberPropertyAnnotation).SingleOrDefault();

            payloadElement.Annotations.Remove(annotation);

            this.VisitProperty(payloadElement, payloadElement.Value);
        }
コード例 #8
0
        /// <summary>
        /// Fix up expected collection parameter payload element for comparison.
        /// </summary>
        /// <param name="expectedResultPayloadElement"></param>
        /// <returns>Modified expected collection payload element</returns>
        internal static ODataPayloadElement FixupExpectedCollectionParameterPayloadElement(ODataPayloadElement expectedResultPayloadElement)
        {
            ComplexInstance expected = expectedResultPayloadElement as ComplexInstance;

            if (expected != null)
            {
                List <ComplexMultiValueProperty>   propertiesToReplace   = new List <ComplexMultiValueProperty>();
                List <PrimitiveMultiValueProperty> replacementProperties = new List <PrimitiveMultiValueProperty>();
                foreach (PropertyInstance pi in expected.Properties)
                {
                    PrimitiveMultiValueProperty primitiveCollectionProperty = pi as PrimitiveMultiValueProperty;
                    ComplexMultiValueProperty   complexCollectionProperty   = pi as ComplexMultiValueProperty;
                    if (primitiveCollectionProperty != null)
                    {
                        // collection parameter is an array of element without type name or result wrapper
                        if (primitiveCollectionProperty.Value.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().Any(a => !a.Value))
                        {
                            primitiveCollectionProperty.Value.FullTypeName = null;
                        }
                    }
                    else if (complexCollectionProperty != null)
                    {
                        if (complexCollectionProperty.Value.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().Any(a => !a.Value))
                        {
                            // collection parameter is an array of element without type name or result wrapper
                            complexCollectionProperty.Value.FullTypeName = null;

                            // replace empty ComplexMultiValueProperty with empty PrimitiveMultiValueProperty for comparison since they have the same payload
                            if (complexCollectionProperty.Value.Count == 0)
                            {
                                PrimitiveMultiValueProperty replacementProperty = new PrimitiveMultiValueProperty(complexCollectionProperty.Name, null);
                                replacementProperty.Value.IsNull = complexCollectionProperty.Value.IsNull;
                                foreach (var annotation in complexCollectionProperty.Annotations)
                                {
                                    replacementProperty.Annotations.Add(annotation);
                                }

                                propertiesToReplace.Add(complexCollectionProperty);
                                replacementProperties.Add(replacementProperty);
                            }
                        }
                    }
                }

                for (int i = 0; i < propertiesToReplace.Count; i++)
                {
                    expected.Replace(propertiesToReplace[i], replacementProperties[i]);
                }

                return(expected);
            }

            return(expectedResultPayloadElement);
        }
コード例 #9
0
            /// <summary>
            /// Visits a payload element whose root is a ComplexMultiValueProperty.
            /// </summary>
            /// <param name="expected">The root node of payload element being visited.</param>
            public void Visit(ComplexMultiValueProperty expected)
            {
                ExceptionUtilities.CheckArgumentNotNull(expected, "expected");
                var observed = this.GetNextObservedElement <ComplexMultiValueProperty>();

                using (this.Assert.WithMessage("Complex multi-value property '{0}' did not match expectation", expected.Name))
                {
                    this.Assert.AreEqual(expected.Name, observed.Name, "Property name did not match expectation");

                    this.CompareAnnotations(expected.Annotations, observed.Annotations);
                    this.WrapAccept(expected.Value, observed.Value);
                }
            }
コード例 #10
0
            /// <summary>
            /// Visits a payload element whose root is a ComplexCollectionProperty.
            /// </summary>
            /// <param name="payloadElement">The root node of payload element being visited.</param>
            public void Visit(ComplexMultiValueProperty payloadElement)
            {
                bool needsWrapping = this.isRootElement;

                if (needsWrapping)
                {
                    this.isRootElement = false;
                    this.writer.StartObjectScope();
                }

                this.writer.WriteName(payloadElement.Name);

                // if an annotation is present that specifies not to use the wrapper, don't
                bool useResultsWrapper = !payloadElement.Value.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().Any(a => !a.Value);

                if (useResultsWrapper)
                {
                    this.writer.StartObjectScope();

                    if (payloadElement.Value.FullTypeName != null)
                    {
                        this.writer.WriteName("__metadata");
                        this.writer.StartObjectScope();
                        this.writer.WriteName("type");
                        this.writer.WriteString(payloadElement.Value.FullTypeName);
                        this.writer.EndScope();
                    }

                    this.writer.WriteName("results");
                }

                if (payloadElement.Value.IsNull)
                {
                    this.writer.WriteNull();
                }
                else
                {
                    this.Recurse(payloadElement.Value);
                }

                if (useResultsWrapper)
                {
                    this.writer.EndScope();
                }

                if (needsWrapping)
                {
                    this.writer.EndScope();
                }
            }
コード例 #11
0
        /// <summary>
        /// Creates a new MultiValue property and sets the value to an empty collection that will be filled when visiting the complex instances.
        /// </summary>
        /// <param name="payloadElement">The complex MultiValue property to process.</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            object parent = null;

            if (this.items.Any())
            {
                parent = this.items.Peek();
            }

            var value = new ODataCollectionValue()
            {
                Items    = new List <object>(),
                TypeName = payloadElement.Value.FullTypeName
            };

            this.items.Push(value);
            base.Visit(payloadElement);

            var odataProperty = new ODataProperty()
            {
                Name  = payloadElement.Name,
                Value = value
            };

            if (parent != null)
            {
                var entry = parent as ODataResource;
                if (entry != null)
                {
                    var properties = (List <ODataProperty>)entry.Properties;
                    properties.Add(odataProperty);
                }

                var complexValue = parent as ODataComplexValue;
                if (complexValue != null)
                {
                    var properties = (List <ODataProperty>)complexValue.Properties;
                    properties.Add(odataProperty);
                }

                // Remove property from items as it has been added to parent.
                this.items.Pop();
            }
            else
            {
                // Remove the ODataCollectionValue and add the ODataProperty.
                this.items.Pop();
                this.items.Push(odataProperty);
            }
        }
コード例 #12
0
        /// <summary>
        /// Visits the children of the given payload element and replaces it with a copy if any child changes
        /// </summary>
        /// <param name="payloadElement">The payload element to potentially replace</param>
        /// <returns>The original element or a copy to replace it with</returns>
        public virtual ODataPayloadElement Visit(ComplexMultiValueProperty payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
            var replacedCollection = this.Recurse(payloadElement.Value) as ComplexMultiValue;

            ExceptionUtilities.CheckObjectNotNull(replacedCollection, "Replaced complex collection was null or wrong type");

            if (!this.ShouldReplace(payloadElement.Value, replacedCollection))
            {
                return(payloadElement);
            }

            return(payloadElement.ReplaceWith(new ComplexMultiValueProperty(payloadElement.Name, replacedCollection)));
        }
コード例 #13
0
        /// <summary>
        /// Visits a payload element whose root is a ComplexMultiValueProperty.
        /// </summary>
        /// <param name="payloadElement">The root node of the payload element being visited.</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            base.Visit(payloadElement);

            if (this.CurrentElementIsRoot())
            {
                Func <MemberProperty, bool> matchesProperty =
                    (p) =>
                {
                    if (p.Name == payloadElement.Name && p.PropertyType is CollectionDataType)
                    {
                        var complexElementType = ((CollectionDataType)p.PropertyType).ElementDataType as ComplexDataType;
                        return(complexElementType != null && payloadElement.Value.FullTypeName == "Collection(" + complexElementType.Definition.FullName + ")");
                    }

                    return(false);
                };

                Func <IEdmProperty, bool> EdmMatchesProperty =
                    (p) =>
                {
                    if (p.Name == payloadElement.Name && p.DeclaringType as IEdmCollectionType != null)
                    {
                        var complexElementType = ((IEdmCollectionType)p.DeclaringType).ElementType as IEdmComplexType;
                        return(complexElementType != null && payloadElement.Value.FullTypeName == "Collection(" + complexElementType.FullName() + ")");
                    }

                    return(false);
                };

                var valueTypeAnnotation = payloadElement.Value.Annotations.OfType <EntityModelTypeAnnotation>().SingleOrDefault();

                if (valueTypeAnnotation != null)
                {
                    if (valueTypeAnnotation.EdmModelType != null)
                    {
                        var edmEntityType = valueTypeAnnotation.EdmModelType;
                        this.AddExpectedTypeToProperty(payloadElement, edmEntityType, EdmMatchesProperty);
                    }
                }
                else
                {
                    var edmEntityType = this.ResolvePropertyEdmDataType(payloadElement.Value.FullTypeName);
                    this.AddExpectedTypeToProperty(payloadElement, edmEntityType, EdmMatchesProperty);
                }
            }

            this.AnnotateIfOpenProperty(payloadElement, payloadElement.Value);
        }
コード例 #14
0
        /// <summary>
        /// Build QueryValue from action response payload
        /// </summary>
        /// <param name="payload">response payload element</param>
        /// <param name="queryType">query type to build</param>
        /// <returns>query value that represents the payload</returns>
        private QueryValue BuildQueryValueForActionResponse(ODataPayloadElement payload, QueryType queryType)
        {
            EntitySetInstance           entitySetInstance           = payload as EntitySetInstance;
            PrimitiveProperty           primitiveProperty           = payload as PrimitiveProperty;
            ComplexProperty             complexProperty             = payload as ComplexProperty;
            PrimitiveMultiValueProperty primitiveMultiValueProperty = payload as PrimitiveMultiValueProperty;
            ComplexMultiValueProperty   complexMultiValueProperty   = payload as ComplexMultiValueProperty;
            PrimitiveCollection         primitiveCollection         = payload as PrimitiveCollection;
            ComplexInstanceCollection   complexInstanceCollection   = payload as ComplexInstanceCollection;

            if (entitySetInstance != null)
            {
                var xmlBaseAnnotations = payload.Annotations.OfType <XmlBaseAnnotation>();
                var collectionType     = this.currentExpression.ExpressionType as QueryCollectionType;
                ExceptionUtilities.CheckObjectNotNull(collectionType, "Cannot cast expression type to QueryCollectionType.");
                var elementType = collectionType.ElementType as QueryEntityType;
                return(this.BuildFromEntitySetInstance(entitySetInstance, elementType, xmlBaseAnnotations));
            }
            else if (primitiveProperty != null)
            {
                return(this.PayloadElementToQueryValueConverter.Convert(primitiveProperty.Value, queryType));
            }
            else if (complexProperty != null)
            {
                return(this.PayloadElementToQueryValueConverter.Convert(complexProperty.Value, queryType));
            }
            else if (primitiveMultiValueProperty != null)
            {
                return(this.PayloadElementToQueryValueConverter.Convert(primitiveMultiValueProperty.Value, queryType));
            }
            else if (complexMultiValueProperty != null)
            {
                return(this.PayloadElementToQueryValueConverter.Convert(complexMultiValueProperty.Value, queryType));
            }
            else if (primitiveCollection != null)
            {
                return(this.PayloadElementToQueryValueConverter.Convert(primitiveCollection, queryType));
            }
            else if (complexInstanceCollection != null)
            {
                return(this.PayloadElementToQueryValueConverter.Convert(complexInstanceCollection, queryType));
            }
            else
            {
                ExceptionUtilities.CheckArgumentNotNull(payload as EntityInstance, "Unexpected response payload type: " + payload.ElementType + ".");
                return(this.PayloadElementToQueryValueConverter.Convert(payload, queryType));
            }
        }
コード例 #15
0
        /// <summary>
        /// Normalizes complex multi-value properties, potentially replacing them with complex collections if the metadata indicates the payload is from a service operation
        /// </summary>
        /// <param name="payloadElement">The payload element to potentially replace</param>
        /// <returns>The original element or a copy to replace it with</returns>
        public override ODataPayloadElement Visit(ComplexMultiValueProperty payloadElement)
        {
            var replaced = base.Visit(payloadElement);
            if (replaced.ElementType == ODataPayloadElementType.ComplexMultiValueProperty)
            {
                payloadElement = (ComplexMultiValueProperty)replaced;
                if (this.ShouldReplaceWithCollection(payloadElement, payloadElement.Value.IsNull, payloadElement.Value.FullTypeName))
                {
                    return payloadElement
                        .ReplaceWith(new ComplexInstanceCollection(payloadElement.Value.ToArray()))
                        .WithAnnotations(new CollectionNameAnnotation() { Name = payloadElement.Name });
                }
            }

            return replaced;
        }
コード例 #16
0
        /// <summary>
        /// Creates a new MultiValue property and sets the value to an empty collection that will be filled when visiting the complex instances.
        /// </summary>
        /// <param name="payloadElement">The complex MultiValue property to process.</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            var odataProperty = new ODataProperty()
            {
                Name  = payloadElement.Name,
                Value = new ODataCollectionValue()
                {
                    Items    = new List <object>(),
                    TypeName = payloadElement.Value.FullTypeName
                }
            };

            this.currentProperties.Add(odataProperty);

            base.Visit(payloadElement);
        }
コード例 #17
0
            /// <summary>
            /// Visits a complex multivalue property and clears its type name.
            /// Note: this has to be done at the property level rather than just at the multivalue in order to maintain the CLR type stack.
            /// </summary>
            /// <param name="payloadElement">The complex multivalue property</param>
            public override void Visit(ComplexMultiValueProperty payloadElement)
            {
                this.VisitProperty(
                    payloadElement,
                    payloadElement.Value,
                    () =>
                {
                    payloadElement.Value.FullTypeName = null;
                    if (this.contextData.ResolveName != null)
                    {
                        string elementName = this.contextData.ResolveName(this.typeStack.Peek());
                        payloadElement.Value.FullTypeName = string.Concat(ODataConstants.BeginMultiValueTypeIdentifier, elementName, ODataConstants.EndMultiValueTypeNameIdentifier);
                    }

                    payloadElement.Value.ForEach(v => v.FullTypeName = null);
                });
            }
コード例 #18
0
        /// <summary>
        /// Normalizes complex multi-value properties, potentially replacing them with complex collections if the metadata indicates the payload is from a service operation
        /// </summary>
        /// <param name="payloadElement">The payload element to potentially replace</param>
        /// <returns>The original element or a copy to replace it with</returns>
        public override ODataPayloadElement Visit(ComplexMultiValueProperty payloadElement)
        {
            var replaced = base.Visit(payloadElement);

            if (replaced.ElementType == ODataPayloadElementType.ComplexMultiValueProperty)
            {
                payloadElement = (ComplexMultiValueProperty)replaced;
                if (this.ShouldReplaceWithCollection(payloadElement, payloadElement.Value.IsNull, payloadElement.Value.FullTypeName))
                {
                    return(payloadElement
                           .ReplaceWith(new ComplexInstanceCollection(payloadElement.Value.ToArray()))
                           .WithAnnotations(new CollectionNameAnnotation()
                    {
                        Name = payloadElement.Name
                    }));
                }
            }

            return(replaced);
        }
コード例 #19
0
        /// <summary>
        /// Converts the ComplexMultiValueProperty into a NavigationPropertyInstance if the base returned an EntitySetInstance
        /// </summary>
        /// <param name="payloadElement">The payload element to potentially replace</param>
        /// <returns>The original element or a copy to replace it with</returns>
        public override ODataPayloadElement Visit(ComplexMultiValueProperty payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
            var replacedCollection = this.Recurse(payloadElement.Value);

            if (!this.ShouldReplace(payloadElement.Value, replacedCollection))
            {
                return(payloadElement);
            }

            var complexmulti = replacedCollection as ComplexMultiValue;

            if (complexmulti != null)
            {
                return(payloadElement.ReplaceWith(new ComplexMultiValueProperty(payloadElement.Name, complexmulti)));
            }

            var entityset = replacedCollection as EntitySetInstance;

            ExceptionUtilities.CheckObjectNotNull(entityset, "Replaced collection should be either ComplexMultiValue or EntitySetInstance");
            return(payloadElement.ReplaceWith(new NavigationPropertyInstance(payloadElement.Name, replacedCollection)));
        }
コード例 #20
0
        private static ComplexInstance GenerateSimilarComplexInstance(IRandomNumberGenerator random, ComplexInstance currentInstance, bool randomizePropertyValues = false)
        {
            ComplexInstance instance = ((ComplexInstance)currentInstance.DeepCopy());

            if (!randomizePropertyValues)
            {
                return(instance);
            }

            foreach (var property in instance.Properties)
            {
                PrimitiveProperty primitive = property as PrimitiveProperty;
                if (primitive != null)
                {
                    primitive.Value = TestValues.GetDifferentPrimitiveValue(primitive.Value);
                }

                ComplexProperty complex = property as ComplexProperty;
                if (complex != null)
                {
                    complex.Value = GenerateSimilarComplexInstance(random, complex.Value);
                }

                PrimitiveMultiValueProperty pmultival = property as PrimitiveMultiValueProperty;
                if (pmultival != null)
                {
                    pmultival.Value = GenerateSimilarPrimitiveMultiValue(random, pmultival.Value);
                }

                ComplexMultiValueProperty cmultival = property as ComplexMultiValueProperty;
                if (cmultival != null)
                {
                    cmultival.Value = GenerateSimilarComplexMultiValue(random, cmultival.Value);
                }
            }

            return(instance);
        }
コード例 #21
0
        public PropertyInstance MultiValueProperty(MemberProperty memberProperty, object anonymous)
        {
            ExceptionUtilities.CheckArgumentNotNull(memberProperty, "memberProperty");

            var collectionType = memberProperty.PropertyType as CollectionDataType;

            ExceptionUtilities.CheckObjectNotNull(collectionType, "Property '{0}' was not a collection");

            var enumerable = anonymous as IEnumerable;

            ExceptionUtilities.CheckObjectNotNull(enumerable, "Value for property '{0}' was not enumerable");

            var primitiveType = collectionType.ElementDataType as PrimitiveDataType;

            if (primitiveType != null)
            {
                var primitiveCollection = new PrimitiveMultiValueProperty(memberProperty.Name, new PrimitiveMultiValue(primitiveType.BuildMultiValueTypeName(), false));
                foreach (var thing in enumerable)
                {
                    primitiveCollection.Value.Add(this.PrimitiveProperty(new MemberProperty("temp", primitiveType), thing).Value);
                }

                return(primitiveCollection);
            }
            else
            {
                var complexType = collectionType.ElementDataType as ComplexDataType;
                ExceptionUtilities.CheckObjectNotNull(complexType, "Collection property '{0}' did not have a primitive or complex collection type", memberProperty.Name);

                var complexCollection = new ComplexMultiValueProperty(memberProperty.Name, new ComplexMultiValue(complexType.BuildMultiValueTypeName(), false));
                foreach (var thing in enumerable)
                {
                    complexCollection.Value.Add(this.ComplexInstance(complexType.Definition, thing));
                }

                return(complexCollection);
            }
        }
コード例 #22
0
 /// <summary>
 /// Visits a payload element whose root is a ComplexCollectionProperty.
 /// </summary>
 /// <param name="payloadElement">The root node of payload element being visited.</param>
 public override void Visit(ComplexMultiValueProperty payloadElement)
 {
     RemoveChangeAnnotations(payloadElement);
     base.Visit(payloadElement);
 }
コード例 #23
0
        /// <summary>
        /// Visits the payload element
        /// </summary>
        /// <param name="payloadElement">The payload element to visit</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");

            var annotation = payloadElement.Annotations.Where(a => a is MemberPropertyAnnotation).SingleOrDefault();
            payloadElement.Annotations.Remove(annotation);

            this.VisitProperty(payloadElement, payloadElement.Value);
        }
コード例 #24
0
        /// <summary>
        /// Converts the ComplexMultiValueProperty into a NavigationPropertyInstance if the base returned an EntitySetInstance
        /// </summary>
        /// <param name="payloadElement">The payload element to potentially replace</param>
        /// <returns>The original element or a copy to replace it with</returns>
        public override ODataPayloadElement Visit(ComplexMultiValueProperty payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
            var replacedCollection = this.Recurse(payloadElement.Value);
            if (!this.ShouldReplace(payloadElement.Value, replacedCollection))
            {
                return payloadElement;
            }

            var complexmulti = replacedCollection as ComplexMultiValue;
            if (complexmulti != null)
            {
                return payloadElement.ReplaceWith(new ComplexMultiValueProperty(payloadElement.Name, complexmulti));
            }

            var entityset = replacedCollection as EntitySetInstance;
            ExceptionUtilities.CheckObjectNotNull(entityset, "Replaced collection should be either ComplexMultiValue or EntitySetInstance");
            return payloadElement.ReplaceWith(new NavigationPropertyInstance(payloadElement.Name, replacedCollection));
        }
コード例 #25
0
 /// <summary>
 /// Normalizes a complex collection property.
 /// </summary>
 /// <param name="payloadElement">The payload element to normalize.</param>
 public override void Visit(ComplexMultiValueProperty payloadElement)
 {
     base.Visit(payloadElement);
     this.NormalizePropertyName(payloadElement);
 }
コード例 #26
0
        private static ComplexMultiValueProperty GetComplexMultiValueProperty(IRandomNumberGenerator random, EdmModel model = null, ODataVersion version = ODataVersion.V4)
        {
            
            int numinstances = random.ChooseFrom(new[] { 0, 1, 3 });
            var instance = GetComplexInstance(random, model, version);
            var instances = GenerateSimilarComplexInstances(random, instance, numinstances, true);
            var propertyName = "ComplexMultivalue" + instance.FullTypeName;
            var payload = new ComplexMultiValueProperty(propertyName,
                new ComplexMultiValue(propertyName, false, instances.ToArray()));
            if (model != null)
            {
                var entityDataType = instance.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType.Definition as IEdmEntityType;
                ExceptionUtilities.CheckObjectNotNull(entityDataType, "Complex Instance must have an EntityModelTypeAnnotation with an EntityDataType");
                var entityType = model.FindDeclaredType(entityDataType.FullName()) as EdmEntityType;

                ExceptionUtilities.CheckObjectNotNull(entityType, "entityType");
                if (entityType.FindProperty(propertyName) != null)
                {
                    entityType.AddStructuralProperty(propertyName, (model.FindDeclaredType(instance.FullTypeName) as EdmComplexType).ToTypeReference());
                }

                payload.WithTypeAnnotation(entityType);
            }

            return payload;
        }
コード例 #27
0
 public override void Visit(ComplexMultiValueProperty payloadElement)
 {
     base.Visit(payloadElement);
     this.ReplaceExpectedTypeAnnotationIfRootElement(payloadElement);
 }
コード例 #28
0
ファイル: TestParameters.cs プロジェクト: AlineGuan/odata.net
        /// <summary>
        /// Builds a complex instance from the given payloadElements to represent a parameters payload.
        /// </summary>
        /// <param name="payloadElements">Each ODataPayloadElement represents the value for each parameter.</param>
        /// <param name="model">EdmModel instance.</param>
        /// <param name="functionImportName">Name of the function import to add to the model.</param>
        /// <returns></returns>
        private static ComplexInstance PayloadElementsToParameterPayload(ODataPayloadElement[] payloadElements, EdmModel model, string functionImportName)
        {
            EdmOperationImport operationImport = (EdmOperationImport)model.EntityContainer.FindOperationImports(functionImportName).FirstOrDefault();
            EdmOperation operation = (EdmOperation)operationImport.Operation;
            
            var parameterPayload = new ComplexInstance(null, false);
            for (int idx = 0; idx < payloadElements.Length; idx++)
            {
                ODataPayloadElement p = payloadElements[idx];
                string parameterName = "p" + idx;
                PropertyInstance parameter;
                IEdmTypeReference entityModelType = p.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType;
                switch (p.ElementType)
                {
                    case ODataPayloadElementType.PrimitiveValue:
                        object clrValue = ((PrimitiveValue)p).ClrValue;
                        PrimitiveValue primitiveValue = new PrimitiveValue(clrValue == null ? null : clrValue.GetType().FullName, clrValue);
                        primitiveValue.CopyAnnotation<PrimitiveValue, EntityModelTypeAnnotation>(p);
                        parameter = new PrimitiveProperty(parameterName, primitiveValue);
                        operation.AddParameter(parameterName, MetadataUtils.GetPrimitiveTypeReference(primitiveValue.ClrValue.GetType()));
                        break;

                    case ODataPayloadElementType.ComplexInstance:
                        parameter = new ComplexProperty(parameterName, (ComplexInstance)p);
                        operation.AddParameter(parameterName, entityModelType);
                        break;

                    case ODataPayloadElementType.PrimitiveMultiValue:
                        PrimitiveMultiValue primitiveMultiValue = (PrimitiveMultiValue)p;
                        if (primitiveMultiValue.Annotations.OfType<JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null)
                        {
                            primitiveMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false));
                        }

                        parameter = new PrimitiveMultiValueProperty(parameterName, primitiveMultiValue);
                        operation.AddParameter(parameterName, entityModelType);
                        break;

                    case ODataPayloadElementType.ComplexMultiValue:
                        ComplexMultiValue complexMultiValue = (ComplexMultiValue)p;
                        if (complexMultiValue.Annotations.OfType<JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null)
                        {
                            complexMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false));
                        }

                        parameter = new ComplexMultiValueProperty(parameterName, complexMultiValue);
                        operation.AddParameter(parameterName, entityModelType);
                        break;

                    case ODataPayloadElementType.EntityInstance:
                        parameter = new NavigationPropertyInstance(parameterName, (EntityInstance)p);
                        operation.AddParameter(parameterName, entityModelType);
                        break;

                    case ODataPayloadElementType.EntitySetInstance:
                        parameter = new NavigationPropertyInstance(parameterName, (EntitySetInstance)p);
                        operation.AddParameter(parameterName, entityModelType);
                        break;

                    default:
                        throw new NotSupportedException("PayloadElementsToParameterPayload() is called on unsupported ODataPayloadElement type: " + p.ElementType);
                }

                parameterPayload.Add(parameter);
            }

            parameterPayload.ExpectedFunctionImport(operationImport);
            return parameterPayload;
        }
コード例 #29
0
        public PropertyInstance MultiValuePropertyEmptyOrNull(MemberProperty memberProperty, object value)
        {
            var bagPropertyType = memberProperty.PropertyType as CollectionDataType;
            ExceptionUtilities.CheckObjectNotNull(bagPropertyType, "Expected property to be a BagProperty instead its a '{0}'", memberProperty.PropertyType);
            
            DataType elementDataType = bagPropertyType.ElementDataType;
            if (value == null)
            {
                return new NullPropertyInstance(memberProperty.Name, elementDataType.BuildMultiValueTypeName());
            }
            else
            {
                ExceptionUtilities.Assert(value == EmptyData.Value, "value MUST be null or EmptyData.Value");
                PropertyInstance collectionProperty = null;
                if (elementDataType is ComplexDataType)
                {
                    collectionProperty = new ComplexMultiValueProperty(memberProperty.Name, new ComplexMultiValue(elementDataType.BuildMultiValueTypeName(), false));
                }
                else
                {
                    ExceptionUtilities.Assert(elementDataType is PrimitiveDataType, "DataType is not a PrimitiveDataType '{0}'", elementDataType);
                    collectionProperty = new PrimitiveMultiValueProperty(memberProperty.Name, new PrimitiveMultiValue(elementDataType.BuildMultiValueTypeName(), false));
                }

                // Add an empty one if specified to
                return collectionProperty;
            }
        }
コード例 #30
0
            /// <summary>
            /// Visits the payload element.
            /// </summary>
            /// <param name="payloadElement">The payload element to visit.</param>
            public override void Visit(ComplexMultiValueProperty payloadElement)
            {
                var observed = this.GetNextObservedElement <ComplexMultiValueProperty>();

                this.WrapAccept(payloadElement.Value, observed.Value);
            }
コード例 #31
0
        /// <summary>
        /// Creates a new MultiValue property and sets the value to an empty collection that will be filled when visiting the complex instances.
        /// </summary>
        /// <param name="payloadElement">The complex MultiValue property to process.</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            object parent = null;
            if (this.items.Any())
            {
                parent = this.items.Peek();
            }

            var value = new ODataCollectionValue()
            {
                Items = new List<object>(),
                TypeName = payloadElement.Value.FullTypeName
            };

            this.items.Push(value);
            base.Visit(payloadElement);

            var odataProperty = new ODataProperty()
            {
                Name = payloadElement.Name,
                Value = value
            };
            
            if (parent != null)
            {
                var entry = parent as ODataEntry;
                if (entry != null)
                {
                    var properties = (List<ODataProperty>)entry.Properties;
                    properties.Add(odataProperty);
                }

                var complexValue = parent as ODataComplexValue;
                if (complexValue != null)
                {
                    var properties = (List<ODataProperty>)complexValue.Properties;
                    properties.Add(odataProperty);
                }

                // Remove property from items as it has been added to parent.
                this.items.Pop();
            }
            else
            {
                // Remove the ODataCollectionValue and add the ODataProperty.
                this.items.Pop();
                this.items.Push(odataProperty);
            }
        }
コード例 #32
0
 /// <summary>
 /// Visits the payload element
 /// </summary>
 /// <param name="payloadElement">The payload element to visit</param>
 public virtual void Visit(ComplexMultiValueProperty payloadElement)
 {
     this.VisitProperty(payloadElement, payloadElement.Value);
 }
コード例 #33
0
 /// <summary>
 /// Visits the payload element
 /// </summary>
 /// <param name="payloadElement">The payload element to visit</param>
 public override void Visit(ComplexMultiValueProperty payloadElement)
 {
     ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
     this.SerializeMultiValueProperty <ComplexMultiValue, ComplexInstance>(payloadElement);
 }
コード例 #34
0
 /// <summary>
 /// Normalizes a complex collection property.
 /// </summary>
 /// <param name="payloadElement">The payload element to normalize.</param>
 public override void Visit(ComplexMultiValueProperty payloadElement)
 {
     base.Visit(payloadElement);
     this.NormalizePropertyName(payloadElement);
 }
コード例 #35
0
 public override void Visit(ComplexMultiValueProperty payloadElement)
 {
     base.Visit(payloadElement);
     this.ReplaceExpectedTypeAnnotationIfRootElement(payloadElement);
 }
コード例 #36
0
            /// <summary>
            /// Visits a payload element whose root is a ComplexMultiValueProperty.
            /// </summary>
            /// <param name="payloadElement">The root node of payload element being visited.</param>
            public void Visit(ComplexMultiValueProperty payloadElement)
            {
                ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");

                var current = this.expectedValueStack.Peek();
                var value = current as QueryCollectionValue;
                ExceptionUtilities.CheckObjectNotNull(value, "Value was not a collection. Value was: '{0}'", current.ToString());

                this.RecurseWithMessage(payloadElement.Value, value, "Complex multi-value property '{0}' did not match expectation", payloadElement.Name);
            }
コード例 #37
0
        /// <summary>
        /// Deserializes a collection property
        /// </summary>
        /// <param name="propertyElement">The xml element representing the property</param>
        /// <returns>The deserialized property</returns>
        private PropertyInstance DeserializeCollectionProperty(XElement propertyElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(propertyElement, "propertyElement");
            ExceptionUtilities.CheckCollectionNotEmpty(propertyElement.Elements(), "propertyElement.Elements()");
            ExceptionUtilities.Assert(propertyElement.Elements().All(e => e.Name == DataServicesElement), "Collection property sub elements had inconsistent names");

            string propertyName = propertyElement.Name.LocalName;

            string fullTypeName = null;
            string bagElementTypeName = null;
            var type = propertyElement.Attribute(MetadataType);
            if (type != null)
            {
                fullTypeName = type.Value;
                bagElementTypeName = ParseBagElementTypeName(type.Value);
            }

            // convert the elements first, then decide if its a primitive or complex collection
            // note that a collection containing all null values will appear as a primitive collection, regardless of what the type really is
            List<PropertyInstance> elements = null;
            if (bagElementTypeName != null)
            {
                elements = propertyElement.Elements().Select(e => this.DeserializeProperty(e, bagElementTypeName)).ToList();
            }
            else
            {
                elements = propertyElement.Elements().Select(e => this.DeserializeProperty(e)).ToList();
            }

            if (elements.OfType<ComplexProperty>().Any())
            {
                var complex = new ComplexMultiValueProperty(propertyName, new ComplexMultiValue(fullTypeName, false));

                foreach (var complexElement in elements)
                {
                    if (complexElement.ElementType == ODataPayloadElementType.NullPropertyInstance)
                    {
                        var nullProperty = complexElement as NullPropertyInstance;
                        complex.Value.Add(new ComplexInstance(nullProperty.FullTypeName, true));
                    }
                    else
                    {
                        ExceptionUtilities.Assert(complexElement.ElementType == ODataPayloadElementType.ComplexProperty, "Complex value collection contained non-complex, non-null value");
                        complex.Value.Add((complexElement as ComplexProperty).Value);
                    }
                }

                return complex;
            }
            else
            {
                var primitive = new PrimitiveMultiValueProperty(propertyName, new PrimitiveMultiValue(fullTypeName, false));

                foreach (var primitiveElement in elements)
                {
                    if (primitiveElement.ElementType == ODataPayloadElementType.NullPropertyInstance)
                    {
                        var nullProperty = primitiveElement as NullPropertyInstance;
                        primitive.Value.Add(new PrimitiveValue(nullProperty.FullTypeName, null));
                    }
                    else
                    {
                        ExceptionUtilities.Assert(primitiveElement.ElementType == ODataPayloadElementType.PrimitiveProperty, "Primitive value collection contained non-primitive, non-null value");
                        primitive.Value.Add((primitiveElement as PrimitiveProperty).Value);
                    }
                }

                return primitive;
            }
        }
コード例 #38
0
        /// <summary>
        /// Creates a new MultiValue property and sets the value to an empty collection that will be filled when visiting the complex instances.
        /// </summary>
        /// <param name="payloadElement">The complex MultiValue property to process.</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            var odataProperty = new ODataProperty()
            {
                Name = payloadElement.Name,
                Value = new ODataCollectionValue() 
                { 
                    Items = new List<object>(),
                    TypeName = payloadElement.Value.FullTypeName
                }
            };
            this.currentProperties.Add(odataProperty);

            base.Visit(payloadElement);
        }
コード例 #39
0
        /// <summary>
        /// Deserializes the element as either a complex, a primitive, or a null property, based on the content
        /// </summary>
        /// <param name="property">The xml to deserialize</param>
        /// <param name="typeNameFallback">TypeName to use instead of the one from the XElement[type] attribute</param>
        /// <returns>A property representing the given xml</returns>
        private PropertyInstance DeserializeProperty(XElement property, string typeNameFallback)
        {
            string propertyName = property.Name.LocalName;

            // get the type name
            string typeNameFromPayload = null;
            XAttribute typeAttribute = property.Attribute(MetadataType);
            if (typeAttribute != null)
            {
                typeNameFromPayload = typeAttribute.Value;
            }

            // set type to be fallback when typeattribute does not exist
            var typeNameForClrTypeLookup = typeNameFromPayload;
            if (typeNameForClrTypeLookup == null && !string.IsNullOrEmpty(typeNameFallback))
            {
                typeNameForClrTypeLookup = typeNameFallback;
            }

            // try to infer the clr type
            Type clrType = null;
            if (!string.IsNullOrEmpty(typeNameForClrTypeLookup))
            {
                ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter");
                clrType = this.PrimitiveDataTypeConverter.ToClrType(typeNameForClrTypeLookup);
            }

            PropertyInstance result;
            if (property.HasElements)
            {
                // must be complex, a multivalue, or spatial
                ExceptionUtilities.CheckObjectNotNull(this.SpatialFormatter, "Cannot safely deserialize element with children without spatial formatter.");

                // try to infer which spatial type hierarchy it is from the type name in the payload
                SpatialTypeKind? kind = null;
                if (clrType != null)
                {
                    SpatialUtilities.TryInferSpatialTypeKind(clrType, out kind);
                }

                object spatialInstance;
                if (this.SpatialFormatter.TryParse(property.Elements().First(), kind, out spatialInstance))
                {
                    ExceptionUtilities.Assert(property.Elements().Count() == 1, "Spatial property had more than 1 sub-element");
                    result = new PrimitiveProperty(propertyName, typeNameFromPayload, spatialInstance);
                }
                else if (property.Elements().All(e => e.Name == DataServicesElement))
                {
                    result = this.DeserializeCollectionProperty(property);
                }
                else
                {
                    result = new ComplexProperty(propertyName, this.DeserializeComplexInstance(property));
                }
            }
            else
            {
                // check for the null attribute
                bool isNull = false;
                XAttribute isNullAttribute = property.Attribute(MetadataNull);
                if (isNullAttribute != null)
                {
                    isNull = bool.Parse(isNullAttribute.Value);
                }

                // If its null and we can't tell whether it is primitive or complex, then return a null marker
                if (isNull && clrType == null)
                {
                    result = new NullPropertyInstance(propertyName, typeNameFromPayload);
                }
                else if (typeNameFromPayload != null && typeNameFromPayload.StartsWith(ODataConstants.BeginMultiValueTypeIdentifier, StringComparison.Ordinal))
                {
                    ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter");

                    string elementTypeName = ParseBagElementTypeName(typeNameFromPayload);
                    if (this.PrimitiveDataTypeConverter.ToClrType(elementTypeName) != null)
                    {
                        result = new PrimitiveMultiValueProperty(propertyName, new PrimitiveMultiValue(typeNameFromPayload, isNull));
                    }
                    else
                    {
                        result = new ComplexMultiValueProperty(propertyName, new ComplexMultiValue(typeNameFromPayload, isNull));
                    }
                }
                else
                {
                    object value;
                    if (isNull)
                    {
                        value = null;
                    }
                    else if (clrType != null)
                    {
                        ExceptionUtilities.CheckObjectNotNull(this.PrimitiveConverter, "PrimitiveConverter has not been set.");
                        value = this.PrimitiveConverter.DeserializePrimitive(property.Value, clrType);
                    }
                    else
                    {
                        value = property.Value;
                    }

                    result = new PrimitiveProperty(propertyName, typeNameFromPayload, value);
                }
            }

            AddXmlBaseAnnotation(result, property);

            return result;
        }
コード例 #40
0
        private void PopulateComplexMultiValuePropertyFromPaths(ComplexInstance instance, MemberProperty memberProperty, string propertyPath, IEnumerable<NamedValue> namedValues, ComplexDataType complexTypeElementDataType)
        {
            int i = 0;
            bool completed = false;

            var complexCollection = new ComplexMultiValueProperty(memberProperty.Name, new ComplexMultiValue(complexTypeElementDataType.BuildMultiValueTypeName(), false));
            while (!completed)
            {
                IEnumerable<NamedValue> complexInstanceNamedValues = namedValues.Where(pp => pp.Name.StartsWith(propertyPath + "." + i + ".", StringComparison.Ordinal)).ToList();
                if (complexInstanceNamedValues.Count() == 0)
                {
                    completed = true;
                }
                else
                {
                    ComplexInstance complexInstance = this.ComplexInstance(complexTypeElementDataType.Definition, propertyPath + "." + i, complexInstanceNamedValues);
                    complexCollection.Value.Add(complexInstance);
                }

                i++;
            }

            if (i > 1)
            {
                instance.Add(complexCollection);
            }
        }
コード例 #41
0
        /// <summary>
        /// Visits a complex property.  A copy of the current properties to be written is taken so that
        /// the complex property can use the global list to track its properties as its children are visited.
        /// Adds the complex property to the list of properties to be written.
        /// </summary>
        /// <param name="payloadElement">The complex property to visit and add</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            // Save off properties of parent
            var arr = this.odataProperties;
            var items = new List<ODataComplexValue>();
            foreach (var item in payloadElement.Value)
            {
                this.odataProperties = new List<ODataProperty>();
                
                this.Visit(item);
                ExceptionUtilities.CheckObjectNotNull(this.odataProperties, "ODataProperties cannot be null");
                var typename = item.FullTypeName.Substring(11, item.FullTypeName.Length - 12);
                var complexValue = new ODataComplexValue() { TypeName = typename };
                complexValue.Properties = this.odataProperties.ToList();//.AsEnumerable();
                items.Add(complexValue);
            }

            //Return the global property list to its initial state with the new complex property added
            this.odataProperties.Clear();
            this.odataProperties.AddRange(arr);

            //create a new complex collection property to add to the list from the properties children
            this.odataProperties.Add(new ODataProperty()
            {
                Name = payloadElement.Name, 
                Value = new ODataCollectionValue()
                {
                    Items = items, TypeName = payloadElement.Value.FullTypeName
                }
            });
        }
コード例 #42
0
            /// <summary>
            /// Visits a complex multivalue property and clears its type name.
            /// Note: this has to be done at the property level rather than just at the multivalue in order to maintain the CLR type stack.
            /// </summary>
            /// <param name="payloadElement">The complex multivalue property</param>
            public override void Visit(ComplexMultiValueProperty payloadElement)
            {
                this.VisitProperty(
                    payloadElement,
                    payloadElement.Value,
                    () =>
                    {
                        payloadElement.Value.FullTypeName = null;
                        if (this.contextData.ResolveName != null)
                        {
                            string elementName = this.contextData.ResolveName(this.typeStack.Peek());
                            payloadElement.Value.FullTypeName = string.Concat(ODataConstants.BeginMultiValueTypeIdentifier, elementName, ODataConstants.EndMultiValueTypeNameIdentifier);
                        }

                        payloadElement.Value.ForEach(v => v.FullTypeName = null);
                    });
            }
コード例 #43
0
        /// <summary>
        /// Deserializes a collection property
        /// </summary>
        /// <param name="propertyElement">The xml element representing the property</param>
        /// <returns>The deserialized property</returns>
        private PropertyInstance DeserializeCollectionProperty(XElement propertyElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(propertyElement, "propertyElement");
            ExceptionUtilities.CheckCollectionNotEmpty(propertyElement.Elements(), "propertyElement.Elements()");
            ExceptionUtilities.Assert(propertyElement.Elements().All(e => e.Name == DataServicesElement), "Collection property sub elements had inconsistent names");

            string propertyName = propertyElement.Name.LocalName;

            string fullTypeName       = null;
            string bagElementTypeName = null;
            var    type = propertyElement.Attribute(MetadataType);

            if (type != null)
            {
                fullTypeName       = type.Value;
                bagElementTypeName = ParseBagElementTypeName(type.Value);
            }

            // convert the elements first, then decide if its a primitive or complex collection
            // note that a collection containing all null values will appear as a primitive collection, regardless of what the type really is
            List <PropertyInstance> elements = null;

            if (bagElementTypeName != null)
            {
                elements = propertyElement.Elements().Select(e => this.DeserializeProperty(e, bagElementTypeName)).ToList();
            }
            else
            {
                elements = propertyElement.Elements().Select(e => this.DeserializeProperty(e)).ToList();
            }

            if (elements.OfType <ComplexProperty>().Any())
            {
                var complex = new ComplexMultiValueProperty(propertyName, new ComplexMultiValue(fullTypeName, false));

                foreach (var complexElement in elements)
                {
                    if (complexElement.ElementType == ODataPayloadElementType.NullPropertyInstance)
                    {
                        var nullProperty = complexElement as NullPropertyInstance;
                        complex.Value.Add(new ComplexInstance(nullProperty.FullTypeName, true));
                    }
                    else
                    {
                        ExceptionUtilities.Assert(complexElement.ElementType == ODataPayloadElementType.ComplexProperty, "Complex value collection contained non-complex, non-null value");
                        complex.Value.Add((complexElement as ComplexProperty).Value);
                    }
                }

                return(complex);
            }
            else
            {
                var primitive = new PrimitiveMultiValueProperty(propertyName, new PrimitiveMultiValue(fullTypeName, false));

                foreach (var primitiveElement in elements)
                {
                    if (primitiveElement.ElementType == ODataPayloadElementType.NullPropertyInstance)
                    {
                        var nullProperty = primitiveElement as NullPropertyInstance;
                        primitive.Value.Add(new PrimitiveValue(nullProperty.FullTypeName, null));
                    }
                    else
                    {
                        ExceptionUtilities.Assert(primitiveElement.ElementType == ODataPayloadElementType.PrimitiveProperty, "Primitive value collection contained non-primitive, non-null value");
                        primitive.Value.Add((primitiveElement as PrimitiveProperty).Value);
                    }
                }

                return(primitive);
            }
        }
コード例 #44
0
            /// <summary>
            /// Visits a payload element whose root is a ComplexCollectionProperty.
            /// </summary>
            /// <param name="payloadElement">The root node of payload element being visited.</param>
            public void Visit(ComplexMultiValueProperty payloadElement)
            {
                bool needsWrapping = this.isRootElement;
                if (needsWrapping)
                {
                    this.isRootElement = false;
                    this.writer.StartObjectScope();
                }

                this.writer.WriteName(payloadElement.Name);

                // if an annotation is present that specifies not to use the wrapper, don't
                bool useResultsWrapper = !payloadElement.Value.Annotations.OfType<JsonCollectionResultWrapperAnnotation>().Any(a => !a.Value);
                if (useResultsWrapper)
                {
                    this.writer.StartObjectScope();

                    if (payloadElement.Value.FullTypeName != null)
                    {
                        this.writer.WriteName("__metadata");
                        this.writer.StartObjectScope();
                        this.writer.WriteName("type");
                        this.writer.WriteString(payloadElement.Value.FullTypeName);
                        this.writer.EndScope();
                    }

                    this.writer.WriteName("results");
                }

                if (payloadElement.Value.IsNull)
                {
                    this.writer.WriteNull();
                }
                else
                {
                    this.Recurse(payloadElement.Value);
                }

                if (useResultsWrapper)
                {
                    this.writer.EndScope();
                }

                if (needsWrapping)
                {
                    this.writer.EndScope();
                }
            }
コード例 #45
0
        /// <summary>
        /// Deserializes the element as either a complex, a primitive, or a null property, based on the content
        /// </summary>
        /// <param name="property">The xml to deserialize</param>
        /// <param name="typeNameFallback">TypeName to use instead of the one from the XElement[type] attribute</param>
        /// <returns>A property representing the given xml</returns>
        private PropertyInstance DeserializeProperty(XElement property, string typeNameFallback)
        {
            string propertyName = property.Name.LocalName;

            // get the type name
            string     typeNameFromPayload = null;
            XAttribute typeAttribute       = property.Attribute(MetadataType);

            if (typeAttribute != null)
            {
                typeNameFromPayload = typeAttribute.Value;
            }

            // set type to be fallback when typeattribute does not exist
            var typeNameForClrTypeLookup = typeNameFromPayload;

            if (typeNameForClrTypeLookup == null && !string.IsNullOrEmpty(typeNameFallback))
            {
                typeNameForClrTypeLookup = typeNameFallback;
            }

            // try to infer the clr type
            Type clrType = null;

            if (!string.IsNullOrEmpty(typeNameForClrTypeLookup))
            {
                ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter");
                clrType = this.PrimitiveDataTypeConverter.ToClrType(typeNameForClrTypeLookup);
            }

            PropertyInstance result;

            if (property.HasElements)
            {
                // must be complex, a multivalue, or spatial
                ExceptionUtilities.CheckObjectNotNull(this.SpatialFormatter, "Cannot safely deserialize element with children without spatial formatter.");

                // try to infer which spatial type hierarchy it is from the type name in the payload
                SpatialTypeKind?kind = null;
                if (clrType != null)
                {
                    SpatialUtilities.TryInferSpatialTypeKind(clrType, out kind);
                }

                object spatialInstance;
                if (this.SpatialFormatter.TryParse(property.Elements().First(), kind, out spatialInstance))
                {
                    ExceptionUtilities.Assert(property.Elements().Count() == 1, "Spatial property had more than 1 sub-element");
                    result = new PrimitiveProperty(propertyName, typeNameFromPayload, spatialInstance);
                }
                else if (property.Elements().All(e => e.Name == DataServicesElement))
                {
                    result = this.DeserializeCollectionProperty(property);
                }
                else
                {
                    result = new ComplexProperty(propertyName, this.DeserializeComplexInstance(property));
                }
            }
            else
            {
                // check for the null attribute
                bool       isNull          = false;
                XAttribute isNullAttribute = property.Attribute(MetadataNull);
                if (isNullAttribute != null)
                {
                    isNull = bool.Parse(isNullAttribute.Value);
                }

                // If its null and we can't tell whether it is primitive or complex, then return a null marker
                if (isNull && clrType == null)
                {
                    result = new NullPropertyInstance(propertyName, typeNameFromPayload);
                }
                else if (typeNameFromPayload != null && typeNameFromPayload.StartsWith(ODataConstants.BeginMultiValueTypeIdentifier, StringComparison.Ordinal))
                {
                    ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter");

                    string elementTypeName = ParseBagElementTypeName(typeNameFromPayload);
                    if (this.PrimitiveDataTypeConverter.ToClrType(elementTypeName) != null)
                    {
                        result = new PrimitiveMultiValueProperty(propertyName, new PrimitiveMultiValue(typeNameFromPayload, isNull));
                    }
                    else
                    {
                        result = new ComplexMultiValueProperty(propertyName, new ComplexMultiValue(typeNameFromPayload, isNull));
                    }
                }
                else
                {
                    object value;
                    if (isNull)
                    {
                        value = null;
                    }
                    else if (clrType != null)
                    {
                        ExceptionUtilities.CheckObjectNotNull(this.PrimitiveConverter, "PrimitiveConverter has not been set.");
                        value = this.PrimitiveConverter.DeserializePrimitive(property.Value, clrType);
                    }
                    else
                    {
                        value = property.Value;
                    }

                    result = new PrimitiveProperty(propertyName, typeNameFromPayload, value);
                }
            }

            AddXmlBaseAnnotation(result, property);

            return(result);
        }
コード例 #46
0
        /// <summary>
        /// Builds a complex instance from the given payloadElements to represent a parameters payload.
        /// </summary>
        /// <param name="payloadElements">Each ODataPayloadElement represents the value for each parameter.</param>
        /// <param name="model">EdmModel instance.</param>
        /// <param name="functionImportName">Name of the function import to add to the model.</param>
        /// <returns></returns>
        private static ComplexInstance PayloadElementsToParameterPayload(ODataPayloadElement[] payloadElements, EdmModel model, string functionImportName)
        {
            EdmOperationImport operationImport = (EdmOperationImport)model.EntityContainer.FindOperationImports(functionImportName).FirstOrDefault();
            EdmOperation       operation       = (EdmOperation)operationImport.Operation;

            var parameterPayload = new ComplexInstance(null, false);

            for (int idx = 0; idx < payloadElements.Length; idx++)
            {
                ODataPayloadElement p           = payloadElements[idx];
                string            parameterName = "p" + idx;
                PropertyInstance  parameter;
                IEdmTypeReference entityModelType = p.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType;
                switch (p.ElementType)
                {
                case ODataPayloadElementType.PrimitiveValue:
                    object         clrValue       = ((PrimitiveValue)p).ClrValue;
                    PrimitiveValue primitiveValue = new PrimitiveValue(clrValue == null ? null : clrValue.GetType().FullName, clrValue);
                    primitiveValue.CopyAnnotation <PrimitiveValue, EntityModelTypeAnnotation>(p);
                    parameter = new PrimitiveProperty(parameterName, primitiveValue);
                    operation.AddParameter(parameterName, MetadataUtils.GetPrimitiveTypeReference(primitiveValue.ClrValue.GetType()));
                    break;

                case ODataPayloadElementType.ComplexInstance:
                    parameter = new ComplexProperty(parameterName, (ComplexInstance)p);
                    operation.AddParameter(parameterName, entityModelType);
                    break;

                case ODataPayloadElementType.PrimitiveMultiValue:
                    PrimitiveMultiValue primitiveMultiValue = (PrimitiveMultiValue)p;
                    if (primitiveMultiValue.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null)
                    {
                        primitiveMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false));
                    }

                    parameter = new PrimitiveMultiValueProperty(parameterName, primitiveMultiValue);
                    operation.AddParameter(parameterName, entityModelType);
                    break;

                case ODataPayloadElementType.ComplexMultiValue:
                    ComplexMultiValue complexMultiValue = (ComplexMultiValue)p;
                    if (complexMultiValue.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null)
                    {
                        complexMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false));
                    }

                    parameter = new ComplexMultiValueProperty(parameterName, complexMultiValue);
                    operation.AddParameter(parameterName, entityModelType);
                    break;

                case ODataPayloadElementType.EntityInstance:
                    parameter = new NavigationPropertyInstance(parameterName, (EntityInstance)p);
                    operation.AddParameter(parameterName, entityModelType);
                    break;

                case ODataPayloadElementType.EntitySetInstance:
                    parameter = new NavigationPropertyInstance(parameterName, (EntitySetInstance)p);
                    operation.AddParameter(parameterName, entityModelType);
                    break;

                default:
                    throw new NotSupportedException("PayloadElementsToParameterPayload() is called on unsupported ODataPayloadElement type: " + p.ElementType);
                }

                parameterPayload.Add(parameter);
            }

            parameterPayload.ExpectedFunctionImport(operationImport);
            return(parameterPayload);
        }
コード例 #47
0
        public void OpenTopLevelPropertiesTest()
        {
            IEdmModel model = TestModels.BuildTestModel();

            var testCases = new OpenPropertyTestCase[]
            {
                new OpenPropertyTestCase
                {
                    DebugDescription = "Integer open property.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", 42),
                    ExpectedPropertyWhenTypeUnavailable = PayloadBuilder.PrimitiveProperty("OpenProperty", 42),
                    ExpectedPropertyType = EdmCoreModel.Instance.GetInt32(false),
                    JsonTypeInformation  = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.Int32\",",
                    Json = "{0}{1}\"" + JsonLightConstants.ODataValuePropertyName + "\":42",
                },
                new OpenPropertyTestCase
                {
                    DebugDescription = "Null open property.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", null),
                    ExpectedPropertyWhenTypeUnavailable = PayloadBuilder.PrimitiveProperty("OpenProperty", null),
                    ExpectedPropertyType = EdmCoreModel.Instance.GetString(true),
                    JsonTypeInformation  = string.Empty,
                    Json = "{0}{1}\"value\":null",
                },
                new OpenPropertyTestCase
                {
                    DebugDescription = "String open property.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", "value"),
                    ExpectedPropertyWhenTypeUnavailable = PayloadBuilder.PrimitiveProperty("OpenProperty", "value"),
                    ExpectedPropertyType = EdmCoreModel.Instance.GetString(true),
                    JsonTypeInformation  = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.String\",",
                    Json = "{0}{1}\"" + JsonLightConstants.ODataValuePropertyName + "\":\"" + JsonLightConstants.ODataValuePropertyName + "\"",
                },
                new OpenPropertyTestCase
                {
                    DebugDescription = "DateTimeOffset open property with type information.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", new DateTimeOffset(2012, 4, 13, 2, 43, 10, 215, TimeSpan.Zero)),
                    ExpectedPropertyWhenTypeUnavailable = PayloadBuilder.PrimitiveProperty("OpenProperty", "2012-04-13T02:43:10.215Z"),
                    ExpectedPropertyType = EdmCoreModel.Instance.GetDateTimeOffset(false),
                    JsonTypeInformation  = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.DateTimeOffset\",",
                    Json = "{0}{1}\"" + JsonLightConstants.ODataValuePropertyName + "\":\"2012-04-13T02:43:10.215Z\"",
                },
            };

            bool[] withExpectedTypes = new bool[] { true, false };
            bool[] withPayloadTypes  = new bool[] { true, false };
            bool[] includeContextUri = new bool[] { true, false };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                withExpectedTypes,
                withPayloadTypes,
                includeContextUri,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testCase, withExpectedType, withPayloadType, withContextUri, testConfiguration) =>
            {
                if (withContextUri && testConfiguration.IsRequest)
                {
                    return;
                }

                string expectedTypeName = testCase.ExpectedPropertyType is IEdmCollectionTypeReference ? "Collection(" + ((IEdmCollectionType)testCase.ExpectedPropertyType.Definition).ElementType.FullName() + ")" : testCase.ExpectedPropertyType.TestFullName();
                string contextUri       = withContextUri ? "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + string.Format("\":\"http://odata.org/test/$metadata#{0}\",", expectedTypeName) : string.Empty;
                string json             = string.Format(
                    CultureInfo.InvariantCulture,
                    testCase.Json,
                    contextUri,
                    withPayloadType ? testCase.JsonTypeInformation : string.Empty);

                bool typeGiven = withExpectedType || withPayloadType || withContextUri;

                if (!typeGiven && testCase.ExpectedPropertyWhenTypeUnavailable == null)
                {
                    testCase.ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_ValueWithoutType");
                }

                PropertyInstance property = typeGiven || testCase.ExpectedPropertyWhenTypeUnavailable == null ? testCase.ExpectedProperty : testCase.ExpectedPropertyWhenTypeUnavailable;
                property = property.DeepCopy();

                if (withExpectedType)
                {
                    property = property.ExpectedPropertyType(testCase.ExpectedPropertyType);
                }

                if (!withPayloadType)
                {
                    ComplexProperty complexProperty = property as ComplexProperty;
                    if (complexProperty != null)
                    {
                        complexProperty.Value.AddAnnotation(new SerializationTypeNameTestAnnotation()
                        {
                            TypeName = null
                        });
                    }
                    else
                    {
                        PrimitiveMultiValueProperty primitiveCollectionProperty = property as PrimitiveMultiValueProperty;
                        if (primitiveCollectionProperty != null)
                        {
                            primitiveCollectionProperty.Value.AddAnnotation(new SerializationTypeNameTestAnnotation()
                            {
                                TypeName = null
                            });
                        }
                        else
                        {
                            ComplexMultiValueProperty complexCollectionProperty = property as ComplexMultiValueProperty;
                            if (complexCollectionProperty != null)
                            {
                                complexCollectionProperty.Value.AddAnnotation(new SerializationTypeNameTestAnnotation()
                                {
                                    TypeName = null
                                });
                            }
                        }
                    }
                }

                ExpectedException expectedException = testCase.ExpectedException;
                if (!withContextUri && !testConfiguration.IsRequest)
                {
                    expectedException = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty");
                }

                PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = testCase.DebugDescription + "[Expected type: " + withExpectedType + ", payload type: " + withPayloadType + "]",
                    PayloadElement   = property
                                       .JsonRepresentation("{" + json + "}"),
                    PayloadEdmModel   = model,
                    ExpectedException = expectedException,
                };

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
コード例 #48
0
        public void NullPropertyNameTest()
        {
            EdmModel model = new EdmModel();

            var complexType1 = new EdmComplexType("TestNS", "ComplexType1");
            complexType1.AddStructuralProperty("StringProperty", EdmPrimitiveTypeKind.String, isNullable: false);
            model.AddElement(complexType1);

            var entityType1 = new EdmEntityType("TestNS", "EntityType1");
            entityType1.AddStructuralProperty("ComplexProperty", new EdmComplexTypeReference(complexType1, isNullable: false));
            model.AddElement(entityType1);

            var entityType2 = new EdmEntityType("TestNS", "EntityType2");
            entityType2.AddStructuralProperty("ComplexCollection", EdmCoreModel.GetCollection(new EdmComplexTypeReference(complexType1, isNullable: false)));
            model.AddElement(entityType2);

            // For these payloads we expect that the product will infer and write the type on the complex and collection properties on the entries.
            // As such we expect a different payload to what we write.
            // Complex Property + expected
            ComplexInstance instance = PayloadBuilder.ComplexValue();
            instance.PrimitiveProperty("StringProperty", "Hello");
            ComplexProperty complexProperty = new ComplexProperty("ComplexProperty", instance);

            ComplexInstance instanceWithType = PayloadBuilder.ComplexValue("TestNS.ComplexType1");
            instanceWithType.PrimitiveProperty("StringProperty", "Hello");
            ComplexProperty complexPropertyWithType = new ComplexProperty("ComplexProperty", instanceWithType);

            // Entity Instance with complex property + expected
            EntityInstance entity1 = new EntityInstance("TestNS.EntityType1", false /*isNull*/);
            entity1.Property(complexProperty);
            entity1.Id = "urn:Id";
            entity1.WithTypeAnnotation(entityType1);
            EntityInstance expectedEntity1 = new EntityInstance("TestNS.EntityType1", false /*isNull*/);
            expectedEntity1.Property(complexPropertyWithType);
            expectedEntity1.Id = "urn:Id";
            expectedEntity1.WithTypeAnnotation(entityType1);

            // Complex Collection Property
            ComplexMultiValueProperty collection = new ComplexMultiValueProperty("ComplexCollection", new ComplexMultiValue(null, false, instance));
            ComplexMultiValueProperty collectionWithType = new ComplexMultiValueProperty("ComplexCollection", new ComplexMultiValue("Collection(TestNS.ComplexType1)", false, instanceWithType));

            // Entity Instance with collection property
            EntityInstance entity2 = new EntityInstance("TestNS.EntityType2", false);
            entity2.Property(collection);
            entity2.Id = "urn:Id";
            entity2.WithTypeAnnotation(entityType2);
            EntityInstance expectedEntity2 = new EntityInstance("TestNS.EntityType2", false);
            expectedEntity2.Property(collectionWithType);
            expectedEntity2.Id = "urn:Id";
            expectedEntity2.WithTypeAnnotation(entityType2);

            PayloadWriterTestDescriptor<ODataPayloadElement>[] testDescriptors = new PayloadWriterTestDescriptor<ODataPayloadElement>[] 
            {
                new PayloadWriterTestDescriptor<ODataPayloadElement>(this.Settings, (ODataPayloadElement)null)
                {
                    PayloadElement = entity1,
                    Model = model,
                    ExpectedResultCallback = (tc) =>
                    {
                        return new PayloadWriterTestExpectedResults(this.ExpectedResultSettings)
                        {
                            ExpectedPayload = expectedEntity1
                        };
                    },
                },
                new PayloadWriterTestDescriptor<ODataPayloadElement>(this.Settings, (ODataPayloadElement)null)
                {
                    PayloadElement = entity2,
                    Model = model,
                    ExpectedResultCallback = (tc) =>
                    {
                        return new PayloadWriterTestExpectedResults(this.ExpectedResultSettings)
                        {
                            ExpectedPayload = expectedEntity2
                        };
                    },
                    
                }
            };

            // TODO: Fix places where we've lost JsonVerbose coverage to add JsonLight
            this.CombinatorialEngineProvider.RunCombinations(
               testDescriptors,
               this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent.Where(tc => tc.Format == ODataFormat.Atom),
               (testDescriptor, testConfiguration) =>
               {
                   testConfiguration = testConfiguration.Clone();
                   testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                   testDescriptor.RunTest(testConfiguration, this.Logger);
               });
        }
コード例 #49
0
        public PropertyInstance MultiValueProperty(MemberProperty memberProperty, object anonymous)
        {
            ExceptionUtilities.CheckArgumentNotNull(memberProperty, "memberProperty");

            var collectionType = memberProperty.PropertyType as CollectionDataType;
            ExceptionUtilities.CheckObjectNotNull(collectionType, "Property '{0}' was not a collection");

            var enumerable = anonymous as IEnumerable;
            ExceptionUtilities.CheckObjectNotNull(enumerable, "Value for property '{0}' was not enumerable");

            var primitiveType = collectionType.ElementDataType as PrimitiveDataType;
            if (primitiveType != null)
            {
                var primitiveCollection = new PrimitiveMultiValueProperty(memberProperty.Name, new PrimitiveMultiValue(primitiveType.BuildMultiValueTypeName(), false));
                foreach (var thing in enumerable)
                {
                    primitiveCollection.Value.Add(this.PrimitiveProperty(new MemberProperty("temp", primitiveType), thing).Value);
                }

                return primitiveCollection;
            }
            else
            {
                var complexType = collectionType.ElementDataType as ComplexDataType;
                ExceptionUtilities.CheckObjectNotNull(complexType, "Collection property '{0}' did not have a primitive or complex collection type", memberProperty.Name);

                var complexCollection = new ComplexMultiValueProperty(memberProperty.Name, new ComplexMultiValue(complexType.BuildMultiValueTypeName(), false));
                foreach (var thing in enumerable)
                {
                    complexCollection.Value.Add(this.ComplexInstance(complexType.Definition, thing));
                }

                return complexCollection;
            }
        }
コード例 #50
0
        /// <summary>
        /// Visits a payload element whose root is a ComplexMultiValueProperty.
        /// </summary>
        /// <param name="payloadElement">The root node of the payload element being visited.</param>
        public override void Visit(ComplexMultiValueProperty payloadElement)
        {
            base.Visit(payloadElement);

            if (this.CurrentElementIsRoot())
            {
                Func<MemberProperty, bool> matchesProperty =
                    (p) =>
                    {
                        if (p.Name == payloadElement.Name && p.PropertyType is CollectionDataType)
                        {
                            var complexElementType = ((CollectionDataType)p.PropertyType).ElementDataType as ComplexDataType;
                            return complexElementType != null && payloadElement.Value.FullTypeName == "Collection(" + complexElementType.Definition.FullName + ")";
                        }

                        return false;
                    };

                Func<IEdmProperty, bool> EdmMatchesProperty =
                        (p) =>
                        {
                            if (p.Name == payloadElement.Name && p.DeclaringType as IEdmCollectionType != null)
                            {
                                var complexElementType = ((IEdmCollectionType)p.DeclaringType).ElementType as IEdmComplexType;
                                return complexElementType != null && payloadElement.Value.FullTypeName == "Collection(" + complexElementType.FullName() + ")";
                            }

                            return false;
                        };

                var valueTypeAnnotation = payloadElement.Value.Annotations.OfType<EntityModelTypeAnnotation>().SingleOrDefault();

                if (valueTypeAnnotation != null)
                {
                    if (valueTypeAnnotation.EdmModelType != null)
                    {
                        var edmEntityType = valueTypeAnnotation.EdmModelType;
                        this.AddExpectedTypeToProperty(payloadElement, edmEntityType, EdmMatchesProperty);
                    }
                }
                else
                {
                    var edmEntityType = this.ResolvePropertyEdmDataType(payloadElement.Value.FullTypeName);
                    this.AddExpectedTypeToProperty(payloadElement, edmEntityType, EdmMatchesProperty);
                }
            }

            this.AnnotateIfOpenProperty(payloadElement, payloadElement.Value);
        }
コード例 #51
0
            /// <summary>
            /// Visits a collection of parameters.
            /// </summary>
            /// <param name="parameters">The parameters to visit.</param>
            protected override ODataPayloadElement VisitParameters(ODataParameters parameters)
            {
                ExceptionUtilities.CheckArgumentNotNull(parameters, "parameters");
                ComplexInstance result = new ComplexInstance();

                result.IsNull = parameters.Count == 0;
                foreach (var parameter in parameters)
                {
                    if (parameter.Value == null)
                    {
                        result.Add(new PrimitiveProperty(parameter.Key, null, null));
                        continue;
                    }

                    ODataComplexValue    odataComplexValue    = parameter.Value as ODataComplexValue;
                    ODataCollectionStart odataCollectionStart = parameter.Value as ODataCollectionStart;

                    if (odataCollectionStart != null)
                    {
                        ODataCollectionItemsObjectModelAnnotation annotation = odataCollectionStart.GetAnnotation <ODataCollectionItemsObjectModelAnnotation>();
                        if (annotation.OfType <ODataComplexValue>().FirstOrDefault() != null)
                        {
                            ComplexMultiValue complexCollection = PayloadBuilder.ComplexMultiValue();
                            foreach (var value in annotation)
                            {
                                complexCollection.Item(this.VisitComplexValue(value as ODataComplexValue) as ComplexInstance);
                            }

                            ComplexMultiValueProperty complexCollectionProperty = new ComplexMultiValueProperty(parameter.Key, complexCollection);
                            result.Add(complexCollectionProperty);
                        }
                        else
                        {
                            PrimitiveMultiValue primitiveCollection = PayloadBuilder.PrimitiveMultiValue();
                            foreach (var value in annotation)
                            {
                                primitiveCollection.Item(value);
                            }

                            PrimitiveMultiValueProperty primitiveCollectionProperty = new PrimitiveMultiValueProperty(parameter.Key, primitiveCollection);
                            result.Add(primitiveCollectionProperty);
                        }
                    }
                    else if (odataComplexValue != null)
                    {
                        ComplexInstance complexInstance = PayloadBuilder.ComplexValue(odataComplexValue.TypeName);
                        complexInstance.IsNull = false;
                        foreach (ODataProperty odataProperty in odataComplexValue.Properties)
                        {
                            complexInstance.Property(odataProperty.Name, this.Visit(odataProperty.Value));
                        }

                        result.Add(new ComplexProperty(parameter.Key, complexInstance));
                    }
                    else
                    {
                        result.Add(new PrimitiveProperty(parameter.Key, null, PayloadBuilder.PrimitiveValue(parameter.Value).ClrValue));
                    }
                }

                return(result);
            }