예제 #1
0
        public static ODataSerializerProvider GetMockODataSerializerProvider(ODataEdmTypeSerializer serializer)
        {
            Mock <ODataSerializerProvider> serializerProvider = new Mock <ODataSerializerProvider>();

            serializerProvider.Setup(sp => sp.GetEdmTypeSerializer(It.IsAny <IEdmTypeReference>())).Returns(serializer);
            return(serializerProvider.Object);
        }
        /// <summary>
        /// Gets an <see cref="T:System.Web.OData.Formatter.Serialization.ODataEdmTypeSerializer"/> for the given edmType.
        ///
        /// </summary>
        /// <param name="edmType">The <see cref="T:Microsoft.OData.Edm.IEdmTypeReference"/>.</param>
        /// <returns>
        /// The <see cref="T:System.Web.OData.Formatter.Serialization.ODataSerializer"/>.
        /// </returns>
        public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
        {
            ODataEdmTypeSerializer serializer = base.GetEdmTypeSerializer(edmType);

            if (serializer is ODataFeedSerializer)
            {
                serializer = _feedSerializer;
            }

            return(serializer);
        }
예제 #3
0
        public void GetEdmTypeSerializer_ReturnODataEnumSerializer_ForEnumType()
        {
            // Arrange
            IEdmTypeReference edmType = new EdmEnumTypeReference(new EdmEnumType("TestModel", "Color"), isNullable: false);

            // Act
            ODataEdmTypeSerializer serializer = _serializerProvider.GetEdmTypeSerializer(edmType);

            // Assert
            Assert.NotNull(serializer);
            Assert.IsType <ODataEnumSerializer>(serializer);
        }
        private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer,
                               ODataSerializerContext writeContext)
        {
            IEdmEntityTypeReference elementType = null;

            if (feedType.IsCollection())
            {
                IEdmTypeReference refer = feedType.AsCollection().ElementType();
                if (refer.IsEntity())
                {
                    elementType = refer.AsEntity();
                }
            }
            Debug.Assert(elementType != null);

            ODataFeed feed = CreateODataFeed(enumerable, feedType.AsCollection(), writeContext);

            Debug.Assert(feed != null);

            ODataEdmTypeSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType);

            Debug.Assert(entrySerializer is CustomEntrySerializer);

            // save this for later to support JSON odata.streaming.
            Uri nextPageLink = feed.NextPageLink;

            feed.NextPageLink = null;

            writer.WriteStart(feed);

            foreach (object entry in enumerable)
            {
                entrySerializer.WriteObjectInline(entry, elementType, writer, writeContext);
            }

            // Subtle and suprising behavior: If the NextPageLink property is set before calling WriteStart(feed),
            // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
            // the next page link is not set when calling WriteStart(feed) but is instead set later on that feed
            // object before calling WriteEnd(), the next page link will be written at the end, as required for
            // odata.streaming=true support.

            if (nextPageLink != null)
            {
                feed.NextPageLink = nextPageLink;
            }

            writer.WriteEnd();
        }
        public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
        {
            switch (edmType.TypeKind())
            {
            case EdmTypeKind.Enum:
                ODataEdmTypeSerializer enumSerializer = base.GetEdmTypeSerializer(edmType);
                return(enumSerializer);

            case EdmTypeKind.Primitive:
                ODataEdmTypeSerializer primitiveSerializer = base.GetEdmTypeSerializer(edmType);
                return(primitiveSerializer);

            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                if (collectionType.ElementType().IsEntity())
                {
                    ODataEdmTypeSerializer feedSerializer = base.GetEdmTypeSerializer(edmType);
                    return(feedSerializer);
                }
                else
                {
                    ODataEdmTypeSerializer collectionSerializer = base.GetEdmTypeSerializer(edmType);
                    return(collectionSerializer);
                }

            case EdmTypeKind.Complex:
                ODataEdmTypeSerializer complexTypeSerializer = base.GetEdmTypeSerializer(edmType);
                return(complexTypeSerializer);

            case EdmTypeKind.Entity:
                ODataEdmTypeSerializer entityTypeSerializer = new ODataEntityTypeSerializer(this);
                return(entityTypeSerializer);

            default:
                return(null);
            }
        }
예제 #6
0
 public CustomSerializerProvider(Func <DefaultODataSerializerProvider, ODataEdmTypeSerializer> factory)
 {
     _entitySerializer = factory(this);
 }
        /// <summary>
        /// Appends the dynamic properties of primitive, enum or the collection of them into the given <see cref="ODataResource"/>.
        /// If the dynamic property is a property of the complex or collection of complex, it will be saved into
        /// the dynamic complex properties dictionary of <paramref name="resourceContext"/> and be written later.
        /// </summary>
        /// <param name="resource">The <see cref="ODataResource"/> describing the resource.</param>
        /// <param name="selectExpandNode">The <see cref="SelectExpandNode"/> describing the response graph.</param>
        /// <param name="resourceContext">The context for the resource instance being written.</param>
        public override void AppendDynamicProperties(ODataResource resource, SelectExpandNode selectExpandNode,
                                                     ResourceContext resourceContext)
        {
            if (!resourceContext.StructuredType.IsOpen || // non-open type
                (!selectExpandNode.SelectAllDynamicProperties && selectExpandNode.SelectedDynamicProperties == null))
            {
                return;
            }

            bool nullDynamicPropertyEnabled = true; // false

            if (resourceContext.EdmObject is EdmDeltaComplexObject || resourceContext.EdmObject is EdmDeltaEntityObject)
            {
                nullDynamicPropertyEnabled = true;
            }

            IEdmStructuredType   structuredType   = resourceContext.StructuredType;
            IEdmStructuredObject structuredObject = resourceContext.EdmObject;
            object value;
            IDelta delta = structuredObject as IDelta;

            if (delta == null)
            {
                PropertyInfo dynamicPropertyInfo = GetDynamicPropertyDictionary(structuredType,
                                                                                resourceContext.EdmModel);
                if (dynamicPropertyInfo == null || structuredObject == null ||
                    !structuredObject.TryGetPropertyValue(dynamicPropertyInfo.Name, out value) || value == null)
                {
                    return;
                }
            }
            else
            {
                value = ((EdmStructuredObject)structuredObject).TryGetDynamicProperties();
            }

            IDictionary <string, object> dynamicPropertyDictionary = (IDictionary <string, object>)value;

            // Build a HashSet to store the declared property names.
            // It is used to make sure the dynamic property name is different from all declared property names.
            //HashSet<string> declaredPropertyNameSet = new HashSet<string>(resource.Properties.Select(p => p.Name));
            List <ODataProperty> dynamicProperties = new List <ODataProperty>();

            // To test SelectedDynamicProperties == null is enough to filter the dynamic properties.
            // Because if SelectAllDynamicProperties == true, SelectedDynamicProperties should be null always.
            // So `selectExpandNode.SelectedDynamicProperties == null` covers `SelectAllDynamicProperties == true` scenario.
            // If `selectExpandNode.SelectedDynamicProperties != null`, then we should test whether the property is selected or not using "Contains(...)".
            IEnumerable <KeyValuePair <string, object> > dynamicPropertiesToSelect =
                dynamicPropertyDictionary.Where(x => selectExpandNode.SelectedDynamicProperties == null || selectExpandNode.SelectedDynamicProperties.Contains(x.Key));

            foreach (KeyValuePair <string, object> dynamicProperty in dynamicPropertiesToSelect)
            {
                if (string.IsNullOrWhiteSpace(dynamicProperty.Key))
                {
                    continue;
                }

                if (dynamicProperty.Value == null)
                {
                    if (nullDynamicPropertyEnabled)
                    {
                        dynamicProperties.Add(new ODataProperty
                        {
                            Name  = dynamicProperty.Key,
                            Value = new ODataNullValue()
                        });
                    }

                    continue;
                }

                //if (declaredPropertyNameSet.Contains(dynamicProperty.Key))
                //{
                //continue;
                //}

                IEdmTypeReference edmTypeReference = GetEdmType(dynamicProperty.Value,
                                                                dynamicProperty.Value.GetType());
                //for non navigational properties it will be null
                if (edmTypeReference == null)
                {
                    dynamicProperties.Add(new ODataProperty
                    {
                        Name  = dynamicProperty.Key,
                        Value = new ODataUntypedValue
                        {
                            RawValue = JsonConvert.SerializeObject(dynamicProperty.Value, new JsonSerializerSettings
                            {
                                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                                TypeNameHandling      = TypeNameHandling.None
                            }),
                            TypeAnnotation = new ODataTypeAnnotation(typeof(string).Name)
                        },
                    });
                }

                else if (edmTypeReference != null)
                {
                    if (edmTypeReference.IsStructured() ||
                        (edmTypeReference.IsCollection() && edmTypeReference.AsCollection().ElementType().IsStructured()))
                    {
                        if (resourceContext.DynamicComplexProperties == null)
                        {
                            resourceContext.DynamicComplexProperties = new ConcurrentDictionary <string, object>();
                        }

                        resourceContext.DynamicComplexProperties.Add(dynamicProperty);
                    }
                    else
                    {
                        ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(edmTypeReference);
                        if (propertySerializer == null)
                        {
                            throw new InvalidOperationException($"Required serilizer for type {edmTypeReference.FullName()} not found");
                        }

                        dynamicProperties.Add(CreateProperty(
                                                  dynamicProperty.Value, edmTypeReference, dynamicProperty.Key, resourceContext.SerializerContext));
                    }
                }
            }

            if (dynamicProperties.Any())
            {
                resource.Properties = resource.Properties.Concat(dynamicProperties);
            }
        }
 public ODataPackageDefaultStreamAwareSerializerProvider()
 {
     this.entitySerializer = new ODataPackageDefaultStreamAwareEntityTypeSerializer(this);
 }