private object ReadNestedResourceSetInline(ODataResourceSetWrapper resourceSetWrapper, IEdmTypeReference edmType, ODataDeserializerContext readContext) { Contract.Assert(resourceSetWrapper != null); Contract.Assert(edmType != null); Contract.Assert(readContext != null); ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmType); if (deserializer == null) { throw new SerializationException(Error.Format(SRResources.TypeCannotBeDeserialized, edmType.FullName())); } IEdmStructuredTypeReference structuredType = edmType.AsCollection().ElementType().AsStructured(); var nestedReadContext = new ODataDeserializerContext { Path = readContext.Path, Model = readContext.Model, }; if (readContext.IsNoClrType) { if (structuredType.IsEntity()) { nestedReadContext.ResourceType = typeof(EdmEntityObjectCollection); } else { nestedReadContext.ResourceType = typeof(EdmComplexObjectCollection); } } else { Type clrType = readContext.Model.GetClrType(structuredType); if (clrType == null) { throw new ODataException( Error.Format(SRResources.MappingDoesNotContainResourceType, structuredType.FullName())); } nestedReadContext.ResourceType = typeof(List <>).MakeGenericType(clrType); } return(deserializer.ReadInline(resourceSetWrapper, edmType, nestedReadContext)); }
private void ApplyDynamicResourceSetInNestedProperty(string propertyName, object resource, IEdmStructuredTypeReference structuredType, ODataResourceSetWrapper resourceSetWrapper, ODataDeserializerContext readContext) { Contract.Assert(resource != null); Contract.Assert(readContext != null); if (String.IsNullOrEmpty(resourceSetWrapper.ResourceSet.TypeName)) { //string message = Error.Format(SRResources.DynamicResourceSetTypeNameIsRequired, propertyName); throw new ODataException("TODO: "); } string elementTypeName = DeserializationHelpers.GetCollectionElementTypeName(resourceSetWrapper.ResourceSet.TypeName, isNested: false); IEdmSchemaType elementType = readContext.Model.FindDeclaredType(elementTypeName); IEdmTypeReference edmTypeReference = elementType.ToEdmTypeReference(true); EdmCollectionTypeReference collectionType = new EdmCollectionTypeReference(new EdmCollectionType(edmTypeReference)); ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(collectionType); if (deserializer == null) { throw new SerializationException(Error.Format(SRResources.TypeCannotBeDeserialized, collectionType.FullName(), typeof(ODataInputFormatter))); } IEnumerable value = ReadNestedResourceSetInline(resourceSetWrapper, collectionType, readContext) as IEnumerable; object result = value; if (value != null) { if (readContext.IsUntyped) { result = value.ConvertToEdmObject(collectionType); } } DeserializationHelpers.SetDynamicProperty(resource, structuredType, EdmTypeKind.Collection, propertyName, result, collectionType, readContext.Model); }
/// <summary> /// Deserializes the given <paramref name="resourceSet"/> under the given <paramref name="readContext"/>. /// </summary> /// <param name="resourceSet">The resource set to deserialize.</param> /// <param name="readContext">The deserializer context.</param> /// <param name="elementType">The element type of the resource set being read.</param> /// <returns>The deserialized resource set object.</returns> public virtual IEnumerable ReadResourceSet(ODataResourceSetWrapper resourceSet, IEdmStructuredTypeReference elementType, ODataDeserializerContext readContext) { if (resourceSet == null) { throw new ArgumentNullException(nameof(resourceSet)); } ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(elementType); if (deserializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, elementType.FullName())); } foreach (ODataResourceWrapper resourceWrapper in resourceSet.Resources) { yield return(deserializer.ReadInline(resourceWrapper, elementType, readContext)); } }
private void ApplyNestedDeltaResourceSet(IEdmProperty nestedProperty, object resource, ODataDeltaResourceSetWrapper deltaResourceSetWrapper, ODataDeserializerContext readContext) { Contract.Assert(nestedProperty != null); Contract.Assert(resource != null); Contract.Assert(readContext != null); IEdmTypeReference edmType = nestedProperty.Type; ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmType, true); if (deserializer == null) { throw new SerializationException(Error.Format(SRResources.TypeCannotBeDeserialized, edmType.FullName())); } IEdmStructuredTypeReference structuredType = edmType.AsCollection().ElementType().AsStructured(); ODataDeserializerContext nestedReadContext = readContext.CloneWithoutType(); if (readContext.IsNoClrType) { nestedReadContext.ResourceType = typeof(EdmChangedObjectCollection); } else { Type clrType = readContext.Model.GetClrType(structuredType); if (clrType == null) { throw new ODataException( Error.Format(SRResources.MappingDoesNotContainResourceType, structuredType.FullName())); } nestedReadContext.ResourceType = typeof(DeltaSet <>).MakeGenericType(clrType); } object value = deserializer.ReadInline(deltaResourceSetWrapper, edmType, nestedReadContext); string propertyName = readContext.Model.GetClrPropertyName(nestedProperty); DeserializationHelpers.SetCollectionProperty(resource, nestedProperty, value, propertyName); }
/// <summary> /// Deserializes the given <paramref name="deltaResourceSet"/> under the given <paramref name="readContext"/>. /// </summary> /// <param name="deltaResourceSet">The delta resource set to deserialize.</param> /// <param name="readContext">The deserializer context.</param> /// <returns>The deserialized resource set object.</returns> public virtual IEnumerable ReadDeltaResourceSet(ODataDeltaResourceSetWrapper deltaResourceSet, ODataDeserializerContext readContext) { if (deltaResourceSet == null) { throw Error.ArgumentNull(nameof(deltaResourceSet)); } if (readContext == null) { throw Error.ArgumentNull(nameof(readContext)); } // resource foreach (ODataResourceBaseWrapper resourceBaseWrapper in deltaResourceSet.ResourceBases) { ODataResourceWrapper resourceWrapper = resourceBaseWrapper as ODataResourceWrapper; ODataDeletedResourceWrapper deletedResourceWrapper = resourceBaseWrapper as ODataDeletedResourceWrapper; if (resourceWrapper != null) { IEdmModel model = readContext.Model; if (model == null) { throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext); } IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType; if (actualType == null) { throw new ODataException(Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName)); } IEdmTypeReference edmTypeReference = actualType.ToEdmTypeReference(true); ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmTypeReference); if (deserializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, edmTypeReference.FullName())); } // TODO: normal resource yield return(deserializer.ReadInline(resourceWrapper, edmTypeReference, readContext)); } else { // TODO: deleted resource } } // Delta links foreach (ODataDeltaLinkBaseWrapper deltaLinkBaseWrapper in deltaResourceSet.DeltaLinks) { ODataDeltaDeletedLinkWrapper deletedLinkWrapper = deltaLinkBaseWrapper as ODataDeltaDeletedLinkWrapper; if (deletedLinkWrapper != null) { yield return(ReadDeltaDeletedLink(deletedLinkWrapper, readContext)); } else { yield return(ReadDeltaLink((ODataDeltaLinkWrapper)deltaLinkBaseWrapper, readContext)); } } }
public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } IEdmAction action = GetAction(readContext); Contract.Assert(action != null); // Create the correct resource type; Dictionary <string, object> payload; if (type == typeof(ODataActionParameters)) { payload = new ODataActionParameters(); } else { payload = new ODataUntypedActionParameters(action); } ODataParameterReader reader = messageReader.CreateODataParameterReader(action); while (reader.Read()) { string parameterName = null; IEdmOperationParameter parameter = null; switch (reader.State) { case ODataParameterReaderState.Value: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); if (parameter.Type.IsPrimitive()) { payload[parameterName] = reader.Value; } else { ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(parameter.Type); payload[parameterName] = deserializer.ReadInline(reader.Value, parameter.Type, readContext); } break; case ODataParameterReaderState.Collection: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(collectionType != null); ODataCollectionValue value = ODataCollectionDeserializer.ReadCollection(reader.CreateCollectionReader()); ODataCollectionDeserializer collectionDeserializer = (ODataCollectionDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType); payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext); break; case ODataParameterReaderState.Resource: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); Contract.Assert(parameter.Type.IsStructured()); ODataReader resourceReader = reader.CreateResourceReader(); object item = resourceReader.ReadResourceOrResourceSet(); ODataResourceDeserializer resourceDeserializer = (ODataResourceDeserializer)DeserializerProvider.GetEdmTypeDeserializer(parameter.Type); payload[parameterName] = resourceDeserializer.ReadInline(item, parameter.Type, readContext); break; case ODataParameterReaderState.ResourceSet: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmCollectionTypeReference resourceSetType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(resourceSetType != null); ODataReader resourceSetReader = reader.CreateResourceSetReader(); object feed = resourceSetReader.ReadResourceOrResourceSet(); ODataResourceSetDeserializer resourceSetDeserializer = (ODataResourceSetDeserializer)DeserializerProvider.GetEdmTypeDeserializer(resourceSetType); object result = resourceSetDeserializer.ReadInline(feed, resourceSetType, readContext); IEdmTypeReference elementTypeReference = resourceSetType.ElementType(); Contract.Assert(elementTypeReference.IsStructured()); IEnumerable enumerable = result as IEnumerable; if (enumerable != null) { if (readContext.IsUntyped) { payload[parameterName] = enumerable.ConvertToEdmObject(resourceSetType); } else { Type elementClrType = readContext.Model.GetClrType(elementTypeReference); IEnumerable castedResult = _castMethodInfo.MakeGenericMethod(elementClrType) .Invoke(null, new[] { result }) as IEnumerable; payload[parameterName] = castedResult; } } break; } } return(payload); }
/// <summary> /// Deserializes the given <paramref name="resourceWrapper"/> under the given <paramref name="readContext"/>. /// </summary> /// <param name="resourceWrapper">The OData resource to deserialize.</param> /// <param name="structuredType">The type of the resource to deserialize.</param> /// <param name="readContext">The deserializer context.</param> /// <returns>The deserialized resource.</returns> public virtual object ReadResource(ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext) { if (resourceWrapper == null) { throw new ArgumentNullException(nameof(resourceWrapper)); } if (readContext == null) { throw new ArgumentNullException(nameof(readContext)); } if (!String.IsNullOrEmpty(resourceWrapper.Resource.TypeName) && structuredType.FullName() != resourceWrapper.Resource.TypeName) { // received a derived type in a base type deserializer. delegate it to the appropriate derived type deserializer. IEdmModel model = readContext.Model; if (model == null) { throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext); } IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType; if (actualType == null) { throw new ODataException(Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName)); } if (actualType.IsAbstract) { string message = Error.Format(SRResources.CannotInstantiateAbstractResourceType, resourceWrapper.Resource.TypeName); throw new ODataException(message); } IEdmTypeReference actualStructuredType; IEdmEntityType actualEntityType = actualType as IEdmEntityType; if (actualEntityType != null) { actualStructuredType = new EdmEntityTypeReference(actualEntityType, isNullable: false); } else { actualStructuredType = new EdmComplexTypeReference(actualType as IEdmComplexType, isNullable: false); } ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(actualStructuredType); if (deserializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, actualEntityType.FullName())); } object resource = deserializer.ReadInline(resourceWrapper, actualStructuredType, readContext); EdmStructuredObject structuredObject = resource as EdmStructuredObject; if (structuredObject != null) { structuredObject.ExpectedEdmType = structuredType.StructuredDefinition(); } return(resource); } else { object resource = CreateResourceInstance(structuredType, readContext); ApplyResourceProperties(resource, resourceWrapper, structuredType, readContext); return(resource); } }
/// <summary> /// Deserializes the given <paramref name="deltaResourceSet"/> under the given <paramref name="readContext"/>. /// </summary> /// <param name="deltaResourceSet">The delta resource set to deserialize.</param> /// <param name="elementType">The element type.</param> /// <param name="readContext">The deserializer context.</param> /// <returns>The deserialized resource set object.</returns> public virtual IEnumerable ReadDeltaResourceSet(ODataDeltaResourceSetWrapper deltaResourceSet, IEdmStructuredTypeReference elementType, ODataDeserializerContext readContext) { if (deltaResourceSet == null) { throw Error.ArgumentNull(nameof(deltaResourceSet)); } if (readContext == null) { throw Error.ArgumentNull(nameof(readContext)); } // Delta Items foreach (ODataItemWrapper itemWrapper in deltaResourceSet.DeltaItems) { // Deleted Link ODataDeltaDeletedLinkWrapper deletedLinkWrapper = itemWrapper as ODataDeltaDeletedLinkWrapper; if (deletedLinkWrapper != null) { yield return(ReadDeltaDeletedLink(deletedLinkWrapper, elementType, readContext)); } // Added Link ODataDeltaLinkWrapper deltaLinkWrapper = itemWrapper as ODataDeltaLinkWrapper; if (deltaLinkWrapper != null) { yield return(ReadDeltaLink(deltaLinkWrapper, elementType, readContext)); } // DeletedResource ODataDeletedResourceWrapper deletedResourceWrapper = itemWrapper as ODataDeletedResourceWrapper; if (deletedResourceWrapper != null) { // TODO: deleted resource yield return(null); } // Added resource or updated resource ODataResourceWrapper resourceWrapper = itemWrapper as ODataResourceWrapper; if (resourceWrapper != null) { IEdmModel model = readContext.Model; if (model == null) { throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext); } IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType; if (actualType == null) { throw new ODataException(Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName)); } IEdmTypeReference edmTypeReference = actualType.ToEdmTypeReference(true); ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmTypeReference); if (deserializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, edmTypeReference.FullName())); } // TODO: normal resource // yield return deserializer.ReadInline(resourceWrapper, edmTypeReference, readContext); if (readContext.IsDeltaOfT) { Type elementClrType = readContext.Model.GetClrType(elementType); Type deltaType = typeof(Deltas.Delta <>).MakeGenericType(elementClrType); Deltas.IDelta delta = Activator.CreateInstance(deltaType) as Deltas.IDelta; yield return(delta); } else { yield return(new EdmDeltaResourceObject(actualType as IEdmEntityType)); } continue; } } }