public void GetEdmTypeDeserializer_ThrowsArgument_EdmType() { // Act & Assert ExceptionAssert.ThrowsArgumentNull( () => _deserializerProvider.GetEdmTypeDeserializer(edmType: null), "edmType"); }
internal static object ConvertTo(ODataParameterValue parameterValue, HttpActionContext actionContext, ModelBindingContext bindingContext) { Contract.Assert(parameterValue != null && parameterValue.EdmType != null); object oDataValue = parameterValue.Value; if (oDataValue == null || oDataValue is ODataNullValue) { return(null); } IEdmTypeReference edmTypeReference = parameterValue.EdmType; ODataDeserializerContext readContext = BuildDeserializerContext(actionContext, bindingContext, edmTypeReference); // complex value ODataComplexValue complexValue = oDataValue as ODataComplexValue; if (complexValue != null) { IEdmComplexTypeReference edmComplexType = edmTypeReference.AsComplex(); Contract.Assert(edmComplexType != null); ODataComplexTypeDeserializer deserializer = (ODataComplexTypeDeserializer)DeserializerProvider.GetEdmTypeDeserializer(edmComplexType); return(deserializer.ReadInline(complexValue, edmComplexType, readContext)); } // collection of primitive, enum, complex ODataCollectionValue collectionValue = oDataValue as ODataCollectionValue; if (collectionValue != null) { return(ConvertCollection(collectionValue, edmTypeReference, bindingContext, readContext)); } // enum value ODataEnumValue enumValue = oDataValue as ODataEnumValue; if (enumValue != null) { IEdmEnumTypeReference edmEnumType = edmTypeReference.AsEnum(); Contract.Assert(edmEnumType != null); ODataEnumDeserializer deserializer = (ODataEnumDeserializer)DeserializerProvider.GetEdmTypeDeserializer(edmEnumType); return(deserializer.ReadInline(enumValue, edmEnumType, readContext)); } // primitive value if (edmTypeReference.IsPrimitive()) { return(EdmPrimitiveHelpers.ConvertPrimitiveValue(oDataValue, bindingContext.ModelType)); } // Entity, Feed, Entity Reference or collection of entity reference return(ConvertFeedOrEntry(oDataValue, edmTypeReference, readContext)); }
internal static object ConvertValue( object odataValue, Type expectedReturnType, IEdmTypeReference propertyType, IEdmModel model, ApiContext apiContext) { ODataDeserializerContext readContext = new ODataDeserializerContext { Model = model }; ODataDeserializerProvider deserializerProvider = apiContext.GetApiService <ODataDeserializerProvider>(); if (odataValue == null) { return(null); } ODataNullValue nullValue = odataValue as ODataNullValue; if (nullValue != null) { return(null); } ODataComplexValue complexValue = odataValue as ODataComplexValue; if (complexValue != null) { ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(propertyType.AsComplex()); return(deserializer.ReadInline(complexValue, propertyType, readContext)); } ODataEnumValue enumValue = odataValue as ODataEnumValue; if (enumValue != null) { ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(propertyType.AsEnum()); return(deserializer.ReadInline(enumValue, propertyType, readContext)); } ODataCollectionValue collection = odataValue as ODataCollectionValue; if (collection != null) { ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(propertyType as IEdmCollectionTypeReference); var collectionResult = deserializer.ReadInline(collection, propertyType, readContext); return(ConvertCollectionType(collectionResult, expectedReturnType)); } return(odataValue); }
private static object ConvertResource(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference, ODataDeserializerContext readContext) { EdmEntitySet tempEntitySet = null; if (edmTypeReference.IsEntity()) { IEdmEntityTypeReference entityType = edmTypeReference.AsEntity(); tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp", entityType.EntityDefinition()); } // TODO: Sam xu, can we use the parameter-less overload ODataReader resourceReader = oDataMessageReader.CreateODataUriParameterResourceReader(tempEntitySet, edmTypeReference.ToStructuredType()); object item = resourceReader.ReadResourceOrResourceSet(); ODataResourceWrapper topLevelResource = item as ODataResourceWrapper; Contract.Assert(topLevelResource != null); ODataDeserializerProvider deserializerProvider = readContext.Request.GetDeserializerProvider(); ODataResourceDeserializer entityDeserializer = (ODataResourceDeserializer)deserializerProvider.GetEdmTypeDeserializer(edmTypeReference); return(entityDeserializer.ReadInline(topLevelResource, edmTypeReference, readContext)); }
/// <summary> /// Gets the deserializer and the expected payload type. /// </summary> /// <param name="request">The HttpRequest.</param> /// <param name="type">The input type.</param> /// <param name="expectedPayloadType">Output the expected payload type.</param> /// <returns>null or the OData deserializer</returns> private static ODataDeserializer GetDeserializer(HttpRequest request, Type type, out IEdmTypeReference expectedPayloadType) { Contract.Assert(request != null); IODataFeature odataFeature = request.ODataFeature(); ODataPath path = odataFeature.Path; IEdmModel model = odataFeature.Model; expectedPayloadType = null; ODataDeserializerProvider deserializerProvider = request.GetSubServiceProvider().GetRequiredService <ODataDeserializerProvider>(); // Get the deserializer using the CLR type first from the deserializer provider. ODataDeserializer deserializer = deserializerProvider.GetODataDeserializer(type, request); if (deserializer == null) { expectedPayloadType = EdmLibHelper.GetExpectedPayloadType(type, path, model); if (expectedPayloadType != null) { // we are in typeless mode, get the deserializer using the edm type from the path. deserializer = deserializerProvider.GetEdmTypeDeserializer(expectedPayloadType); } } return(deserializer); }
private static ODataDeserializer GetDeserializer(Type type, ODataPath path, IEdmModel model, ODataDeserializerProvider deserializerProvider) { if (typeof(IEdmObject).IsAssignableFrom(type)) { // typeless mode. figure out the expected payload type from the OData Path. IEdmType edmType = path.EdmType; if (edmType != null) { IEdmTypeReference expectedPayloadType = EdmLibHelpers.ToEdmTypeReference(edmType, isNullable: false); if (expectedPayloadType.TypeKind() == EdmTypeKind.Collection) { IEdmTypeReference elementType = expectedPayloadType.AsCollection().ElementType(); if (elementType.IsEntity()) { // collection of entities cannot be CREATE/UPDATEd. Instead, the request would contain a single entry. expectedPayloadType = elementType; } } if (expectedPayloadType != null) { return(deserializerProvider.GetEdmTypeDeserializer(expectedPayloadType)); } } } else { TryGetInnerTypeForDelta(ref type); return(deserializerProvider.GetODataDeserializer(model, type)); } return(null); }
private static object ConvertEnumValue(ODataEnumValue enumValue, ref IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext) { IEdmEnumTypeReference edmEnumType; if (propertyType == null) { // dynamic enum property Contract.Assert(!String.IsNullOrEmpty(enumValue.TypeName), "ODataLib should have verified that dynamic enum value has a type name since we provided metadata."); IEdmModel model = readContext.Model; IEdmType edmType = model.FindType(enumValue.TypeName); Contract.Assert(edmType.TypeKind == EdmTypeKind.Enum, "ODataLib should have verified that enum value has a enum resource type."); edmEnumType = new EdmEnumTypeReference(edmType as IEdmEnumType, isNullable: true); propertyType = edmEnumType; } else { edmEnumType = propertyType.AsEnum(); } ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(edmEnumType); return(deserializer.ReadInline(enumValue, propertyType, readContext)); }
private static object ConvertCollectionValue(ODataCollectionValue collection, ref IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext) { IEdmCollectionTypeReference collectionType; if (propertyType == null) { // dynamic collection property Contract.Assert(!String.IsNullOrEmpty(collection.TypeName), "ODataLib should have verified that dynamic collection value has a type name " + "since we provided metadata."); string elementTypeName = GetCollectionElementTypeName(collection.TypeName, isNested: false); IEdmModel model = readContext.Model; IEdmSchemaType elementType = model.FindType(elementTypeName); Contract.Assert(elementType != null); collectionType = new EdmCollectionTypeReference( new EdmCollectionType(elementType.ToEdmTypeReference(isNullable: false))); propertyType = collectionType; } else { collectionType = propertyType as IEdmCollectionTypeReference; Contract.Assert(collectionType != null, "The type for collection must be a IEdmCollectionType."); } ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(collectionType); return(deserializer.ReadInline(collection, collectionType, readContext)); }
private static object ConvertResourceSet(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference, ODataDeserializerContext readContext) { IEdmCollectionTypeReference collectionType = edmTypeReference.AsCollection(); EdmEntitySet tempEntitySet = null; if (collectionType.ElementType().IsEntity()) { tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp", collectionType.ElementType().AsEntity().EntityDefinition()); } // TODO: Sam xu, can we use the parameter-less overload ODataReader odataReader = oDataMessageReader.CreateODataUriParameterResourceSetReader(tempEntitySet, collectionType.ElementType().AsStructured().StructuredDefinition()); ODataResourceSetWrapper resourceSet = odataReader.ReadResourceOrResourceSet() as ODataResourceSetWrapper; ODataDeserializerProvider deserializerProvider = readContext.Request.GetDeserializerProvider(); ODataResourceSetDeserializer resourceSetDeserializer = (ODataResourceSetDeserializer)deserializerProvider.GetEdmTypeDeserializer(collectionType); object result = resourceSetDeserializer.ReadInline(resourceSet, collectionType, readContext); IEnumerable enumerable = result as IEnumerable; if (enumerable != null) { IEnumerable newEnumerable = enumerable; if (collectionType.ElementType().IsEntity()) { newEnumerable = CovertResourceSetIds(enumerable, resourceSet, collectionType, readContext); } if (readContext.IsUntyped) { return(newEnumerable.ConvertToEdmObject(collectionType)); } else { IEdmTypeReference elementTypeReference = collectionType.ElementType(); Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference, readContext.Model); IEnumerable castedResult = CastMethodInfo.MakeGenericMethod(elementClrType) .Invoke(null, new object[] { newEnumerable }) as IEnumerable; return(castedResult); } } return(null); }
public void GetEdmTypeDeserializer_ReturnODataEnumDeserializer_ForEnumType() { // Arrange IEdmTypeReference edmType = new EdmEnumTypeReference(new EdmEnumType("TestModel", "Color"), isNullable: false); // Act ODataEdmTypeDeserializer deserializer = _deserializerProvider.GetEdmTypeDeserializer(edmType); // Assert Assert.NotNull(deserializer); Assert.IsType <ODataEnumDeserializer>(deserializer); }
private static object ConvertCollection(ODataCollectionValue collectionValue, IEdmTypeReference edmTypeReference, Type clrType, string parameterName, ODataDeserializerContext readContext, IServiceProvider requestContainer) { Contract.Assert(collectionValue != null); IEdmCollectionTypeReference collectionType = edmTypeReference as IEdmCollectionTypeReference; Contract.Assert(collectionType != null); ODataDeserializerProvider deserializerProvider = requestContainer.GetRequiredService <ODataDeserializerProvider>(); ODataCollectionDeserializer deserializer = (ODataCollectionDeserializer)deserializerProvider.GetEdmTypeDeserializer(collectionType); object value = deserializer.ReadInline(collectionValue, collectionType, readContext); if (value == null) { return(null); } IEnumerable collection = value as IEnumerable; Contract.Assert(collection != null); Type elementType; if (!clrType.IsCollection(out elementType)) { // EdmEntityCollectionObject and EdmComplexCollectionObject are collection types. throw new ODataException(String.Format(CultureInfo.InvariantCulture, SRResources.ParameterTypeIsNotCollection, parameterName, clrType)); } IEnumerable newCollection; if (CollectionDeserializationHelpers.TryCreateInstance(clrType, collectionType, elementType, out newCollection)) { collection.AddToCollection(newCollection, elementType, parameterName, clrType); if (clrType.IsArray) { newCollection = CollectionDeserializationHelpers.ToArray(newCollection, elementType); } return(newCollection); } return(null); }
/// <summary> /// Gets the <see cref="ODataEdmTypeDeserializer"/> for the given EDM type. /// The proxy provider will get the real provider to return the serializer. /// </summary> /// <param name="edmType">The EDM type.</param> /// <returns>An <see cref="ODataEdmTypeDeserializer"/> that can deserialize the given EDM type.</returns> public override ODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType) { if (this.api != null) { ODataDeserializerProvider provider = api.Context.GetApiService <ODataDeserializerProvider>(); if (provider != null) { return(provider.GetEdmTypeDeserializer(edmType)); } } // In case user uses his own controller or NonFound error for request return(DefaultRestierDeserializerProvider.SingletonInstance.GetEdmTypeDeserializer(edmType)); }
private ODataDeserializer GetDeserializer(Type type, ODataPath path, IEdmModel model, ODataDeserializerProvider deserializerProvider, out IEdmTypeReference expectedPayloadType) { expectedPayloadType = GetExpectedPayloadType(type, path, model); if (expectedPayloadType != null) { return(deserializerProvider.GetEdmTypeDeserializer(expectedPayloadType)); } else { return(deserializerProvider.GetODataDeserializer(model, type, Request)); } }
private ODataDeserializer GetDeserializer(Type type, ODataPath path, IEdmModel model, ODataDeserializerProvider deserializerProvider, out IEdmTypeReference expectedPayloadType) { expectedPayloadType = GetExpectedPayloadType(type, path, model); // Get the deserializer using the CLR type first from the deserializer provider. ODataDeserializer deserializer = deserializerProvider.GetODataDeserializer(model, type, Request); if (deserializer == null && expectedPayloadType != null) { // we are in typeless mode, get the deserializer using the edm type from the path. deserializer = deserializerProvider.GetEdmTypeDeserializer(expectedPayloadType); } return(deserializer); }
/// <summary> /// Convert an OData value into a CLR object. /// </summary> /// <param name="graph">The given object.</param> /// <param name="edmTypeReference">The EDM type of the given object.</param> /// <param name="clrType">The CLR type of the given object.</param> /// <param name="parameterName">The parameter name of the given object.</param> /// <param name="readContext">The <see cref="ODataDeserializerContext"/> use to convert.</param> /// <param name="requestContainer">The dependency injection container for the request.</param> /// <returns>The converted object.</returns> public static object Convert(object graph, IEdmTypeReference edmTypeReference, Type clrType, string parameterName, ODataDeserializerContext readContext, IServiceProvider requestContainer) { if (graph == null || graph is ODataNullValue) { return(null); } // collection of primitive, enum ODataCollectionValue collectionValue = graph as ODataCollectionValue; if (collectionValue != null) { return(ConvertCollection(collectionValue, edmTypeReference, clrType, parameterName, readContext, requestContainer)); } // enum value ODataEnumValue enumValue = graph as ODataEnumValue; if (enumValue != null) { IEdmEnumTypeReference edmEnumType = edmTypeReference.AsEnum(); Contract.Assert(edmEnumType != null); ODataDeserializerProvider deserializerProvider = requestContainer.GetRequiredService <ODataDeserializerProvider>(); ODataEnumDeserializer deserializer = (ODataEnumDeserializer)deserializerProvider.GetEdmTypeDeserializer(edmEnumType); return(deserializer.ReadInline(enumValue, edmEnumType, readContext)); } // primitive value if (edmTypeReference.IsPrimitive()) { ConstantNode node = graph as ConstantNode; return(EdmPrimitiveHelper.ConvertPrimitiveValue(node != null ? node.Value : graph, clrType, readContext.TimeZone)); } // Resource, ResourceSet, Entity Reference or collection of entity reference return(ConvertResourceOrResourceSet(graph, edmTypeReference, readContext)); }
/// <inheritdoc/> public override bool CanReadType(Type type) { if (type == null) { throw Error.ArgumentNull("type"); } if (Request != null) { ODataDeserializerProvider deserializerProvider = Request.GetRequestContainer() .GetRequiredService <ODataDeserializerProvider>(); return(ODataInputFormatterHelper.CanReadType( type, Request.GetModel(), Request.ODataProperties().Path, _payloadKinds, (objectType) => deserializerProvider.GetEdmTypeDeserializer(objectType), (objectType) => deserializerProvider.GetODataDeserializer(objectType, Request))); } return(false); }
/// <inheritdoc/> public override bool CanRead(InputFormatterContext context) { if (context == null) { throw Error.ArgumentNull("context"); } HttpRequest request = context.HttpContext.Request; if (request == null) { throw Error.InvalidOperation(SRResources.ReadFromStreamAsyncMustHaveRequest); } // Ignore non-OData requests. if (request.ODataFeature().Path == null) { return(false); } Type type = context.ModelType; if (type == null) { throw Error.ArgumentNull("type"); } ODataDeserializerProvider deserializerProvider = request.GetRequestContainer().GetRequiredService <ODataDeserializerProvider>(); return(ODataInputFormatterHelper.CanReadType( type, request.GetModel(), request.ODataFeature().Path, _payloadKinds, (objectType) => deserializerProvider.GetEdmTypeDeserializer(objectType), (objectType) => deserializerProvider.GetODataDeserializer(objectType, request))); }
public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) { if (type == null) { throw Error.ArgumentNull("type"); } if (readStream == null) { throw Error.ArgumentNull("readStream"); } if (Request == null) { throw Error.InvalidOperation(SRResources.ReadFromStreamAsyncMustHaveRequest); } object defaultValue = GetDefaultValueForType(type); // If content length is 0 then return default value for this type HttpContentHeaders contentHeaders = (content == null) ? null : content.Headers; if (contentHeaders == null || contentHeaders.ContentLength == 0) { return(Task.FromResult(defaultValue)); } try { Func <ODataDeserializerContext> getODataDeserializerContext = () => { return(new ODataDeserializerContext { Request = Request, }); }; Action <Exception> logErrorAction = (ex) => { if (formatterLogger == null) { throw ex; } formatterLogger.LogError(String.Empty, ex); }; ODataDeserializerProvider deserializerProvider = Request.GetRequestContainer() .GetRequiredService <ODataDeserializerProvider>(); return(Task.FromResult(ODataInputFormatterHelper.ReadFromStream( type, defaultValue, Request.GetModel(), GetBaseAddressInternal(Request), new WebApiRequestMessage(Request), () => ODataMessageWrapperHelper.Create(readStream, contentHeaders, Request.GetODataContentIdMapping(), Request.GetRequestContainer()), (objectType) => deserializerProvider.GetEdmTypeDeserializer(objectType), (objectType) => deserializerProvider.GetODataDeserializer(objectType, Request), getODataDeserializerContext, (disposable) => Request.RegisterForDispose(disposable), logErrorAction))); } catch (Exception ex) { return(TaskHelpers.FromError <object>(ex)); } }
public override async Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) { if (context == null) { throw Error.ArgumentNull("context"); } Type type = context.ModelType; if (type == null) { throw Error.ArgumentNull("type"); } HttpRequest request = context.HttpContext.Request; if (request == null) { throw Error.InvalidOperation(SRResources.ReadFromStreamAsyncMustHaveRequest); } // If content length is 0 then return default value for this type RequestHeaders contentHeaders = request.GetTypedHeaders(); object defaultValue = GetDefaultValueForType(type); if (contentHeaders == null || contentHeaders.ContentLength == 0) { return(InputFormatterResult.Success(defaultValue)); } try { Func <ODataDeserializerContext> getODataDeserializerContext = () => { return(new ODataDeserializerContext { Request = request, }); }; Action <Exception> logErrorAction = (ex) => { ILogger logger = context.HttpContext.RequestServices.GetService <ILogger>(); if (logger == null) { throw ex; } logger.LogError(ex, String.Empty); }; List <IDisposable> toDispose = new List <IDisposable>(); ODataDeserializerProvider deserializerProvider = request.GetRequestContainer().GetRequiredService <ODataDeserializerProvider>(); object result = await ODataInputFormatterHelper.ReadFromStreamAsync( type, defaultValue, request.GetModel(), GetBaseAddressInternal(request), new WebApiRequestMessage(request), () => ODataMessageWrapperHelper.Create(new StreamWrapper(request.Body), request.Headers, request.GetODataContentIdMapping(), request.GetRequestContainer()), (objectType) => deserializerProvider.GetEdmTypeDeserializer(objectType), (objectType) => deserializerProvider.GetODataDeserializer(objectType, request), getODataDeserializerContext, (disposable) => toDispose.Add(disposable), logErrorAction); foreach (IDisposable obj in toDispose) { obj.Dispose(); } return(InputFormatterResult.Success(result)); } catch (Exception ex) { context.ModelState.AddModelError(context.ModelName, ex, context.Metadata); return(InputFormatterResult.Failure()); } }
private static object ConvertComplexValue(ODataComplexValue complexValue, ref IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext) { IEdmComplexTypeReference complexTypeReference = propertyType != null?propertyType.AsComplex() : (IEdmComplexTypeReference) new EdmComplexTypeReference((IEdmType)readContext.Model.FindType(complexValue.TypeName) as IEdmComplexType, true); return(deserializerProvider.GetEdmTypeDeserializer((IEdmTypeReference)complexTypeReference).ReadInline((object)complexValue, propertyType, readContext)); }
private static object ConvertCollectionValue(ODataCollectionValue collection, IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext) { IEdmCollectionTypeReference collectionTypeReference = propertyType as IEdmCollectionTypeReference; return(deserializerProvider.GetEdmTypeDeserializer((IEdmTypeReference)collectionTypeReference).ReadInline((object)collection, (IEdmTypeReference)collectionTypeReference, readContext)); }