/// <inheritdoc/> 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"); } object result = null; HttpContentHeaders contentHeaders = content == null ? null : content.Headers; // If content length is 0 then return default value for this type if (contentHeaders != null && contentHeaders.ContentLength == 0) { result = GetDefaultValueForType(type); } else { bool isPatchMode = TryGetInnerTypeForDelta(ref type); ODataDeserializer deserializer = ODataDeserializerProvider.GetODataDeserializer(type); if (deserializer == null) { throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName); } ODataMessageReader oDataMessageReader = null; ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = true }; try { IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders); oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, ODataDeserializerProvider.EdmModel); ODataDeserializerContext readContext = new ODataDeserializerContext { IsPatchMode = isPatchMode, PatchKeyMode = PatchKeyMode }; result = deserializer.Read(oDataMessageReader, readContext); } finally { if (oDataMessageReader != null) { oDataMessageReader.Dispose(); } } } return(TaskHelpers.FromResult(result)); }
/// <inheritdoc/> 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); } return TaskHelpers.RunSynchronously<object>(() => { object result; HttpContentHeaders contentHeaders = content == null ? null : content.Headers; // If content length is 0 then return default value for this type if (contentHeaders == null || contentHeaders.ContentLength == 0) { result = GetDefaultValueForType(type); } else { IEdmModel model = _request.GetEdmModel(); if (model == null) { throw Error.InvalidOperation(SRResources.RequestMustHaveModel); } Type originalType = type; bool isPatchMode = TryGetInnerTypeForDelta(ref type); ODataDeserializer deserializer = _deserializerProvider.GetODataDeserializer(model, type); if (deserializer == null) { throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName); } ODataMessageReader oDataMessageReader = null; ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = true, MessageQuotas = MessageReaderQuotas }; try { IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders); oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model); ODataPath path = _request == null ? null : _request.GetODataPath(); ODataDeserializerContext readContext = new ODataDeserializerContext { IsPatchMode = isPatchMode, Path = path, Model = model }; if (isPatchMode) { readContext.PatchEntityType = originalType; } result = deserializer.Read(oDataMessageReader, readContext); } catch (Exception e) { if (formatterLogger == null) { throw; } formatterLogger.LogError(String.Empty, e); result = GetDefaultValueForType(type); } finally { if (oDataMessageReader != null) { oDataMessageReader.Dispose(); } } } return result; }); }
/// <summary> /// Creates an <see cref="ODataMaterializer"/> for a response. /// </summary> /// <param name="responseMessage">The response message.</param> /// <param name="responseInfo">The response context.</param> /// <param name="materializerType">The type to materialize.</param> /// <param name="queryComponents">The query components for the request.</param> /// <param name="plan">The projection plan.</param> /// <param name="payloadKind">expected payload kind.</param> /// <returns>A materializer specialized for the given response.</returns> public static ODataMaterializer CreateMaterializerForMessage( IODataResponseMessage responseMessage, ResponseInfo responseInfo, Type materializerType, QueryComponents queryComponents, ProjectionPlan plan, ODataPayloadKind payloadKind) { ODataMessageReader messageReader = CreateODataMessageReader(responseMessage, responseInfo, ref payloadKind); ODataMaterializer result; IEdmType edmType = null; try { ODataMaterializerContext materializerContext = new ODataMaterializerContext(responseInfo); // Since in V1/V2, astoria client allowed Execute<object> and depended on the typeresolver or the wire type name // to get the clr type to materialize. Hence if we see the materializer type as object, we should set the edmtype // to null, since there is no expected type. if (materializerType != typeof(System.Object)) { edmType = responseInfo.TypeResolver.ResolveExpectedTypeForReading(materializerType); } if (payloadKind == ODataPayloadKind.Property && edmType != null) { if (edmType.TypeKind.IsStructured()) { payloadKind = ODataPayloadKind.Resource; } else if (edmType.TypeKind == EdmTypeKind.Collection && (edmType as IEdmCollectionType).ElementType.IsStructured()) { payloadKind = ODataPayloadKind.ResourceSet; } } if (payloadKind == ODataPayloadKind.Resource || payloadKind == ODataPayloadKind.ResourceSet) { // In V1/V2, we allowed System.Object type to be allowed to pass to ExecuteQuery. // Hence we need to explicitly check for System.Object to allow this if (edmType != null && !edmType.TypeKind.IsStructured()) { throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidNonEntityType(materializerType.FullName)); } ODataReaderWrapper reader = ODataReaderWrapper.Create(messageReader, payloadKind, edmType, responseInfo.ResponsePipeline); EntityTrackingAdapter entityTrackingAdapter = new EntityTrackingAdapter(responseInfo.EntityTracker, responseInfo.MergeOption, responseInfo.Model, responseInfo.Context); LoadPropertyResponseInfo loadPropertyResponseInfo = responseInfo as LoadPropertyResponseInfo; if (loadPropertyResponseInfo != null) { result = new ODataLoadNavigationPropertyMaterializer( messageReader, reader, materializerContext, entityTrackingAdapter, queryComponents, materializerType, plan, loadPropertyResponseInfo); } else { result = new ODataReaderEntityMaterializer( messageReader, reader, materializerContext, entityTrackingAdapter, queryComponents, materializerType, plan); } } else { switch (payloadKind) { case ODataPayloadKind.Value: result = new ODataValueMaterializer(messageReader, materializerContext, materializerType, queryComponents.SingleResult); break; case ODataPayloadKind.Collection: result = new ODataCollectionMaterializer(messageReader, materializerContext, materializerType, queryComponents.SingleResult); break; case ODataPayloadKind.Property: case ODataPayloadKind.IndividualProperty: // Top level properties cannot be of entity type. if (edmType != null && (edmType.TypeKind == EdmTypeKind.Entity || edmType.TypeKind == EdmTypeKind.Complex)) { throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidEntityType(materializerType.FullName)); } result = new ODataPropertyMaterializer(messageReader, materializerContext, materializerType, queryComponents.SingleResult); break; case ODataPayloadKind.EntityReferenceLinks: case ODataPayloadKind.EntityReferenceLink: result = new ODataLinksMaterializer(messageReader, materializerContext, materializerType, queryComponents.SingleResult); break; case ODataPayloadKind.Error: var odataError = messageReader.ReadError(); throw new ODataErrorException(odataError.Message, odataError); default: throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidResponsePayload(XmlConstants.DataWebNamespace)); } } return(result); } catch (Exception ex) { if (CommonUtil.IsCatchableExceptionType(ex)) { // Dispose the message reader in all error scenarios. messageReader.Dispose(); } throw; } }
/// <inheritdoc/> 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"); } object result = null; HttpContentHeaders contentHeaders = content == null ? null : content.Headers; // If content length is 0 then return default value for this type if (contentHeaders != null && contentHeaders.ContentLength == 0) { result = GetDefaultValueForType(type); } else { bool isPatchMode = TryGetInnerTypeForDelta(ref type); ODataDeserializer deserializer = ODataDeserializerProvider.GetODataDeserializer(type); if (deserializer == null) { throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName); } ODataMessageReader oDataMessageReader = null; ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = true }; try { IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders); oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, ODataDeserializerProvider.EdmModel); ODataDeserializerContext readContext = new ODataDeserializerContext { IsPatchMode = isPatchMode, PatchKeyMode = PatchKeyMode }; result = deserializer.Read(oDataMessageReader, readContext); } finally { if (oDataMessageReader != null) { oDataMessageReader.Dispose(); } } } return TaskHelpers.FromResult(result); }
/// <inheritdoc/> 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"); } return(TaskHelpers.RunSynchronously <object>(() => { object result; HttpContentHeaders contentHeaders = content == null ? null : content.Headers; // If content length is 0 then return default value for this type if (contentHeaders != null && contentHeaders.ContentLength == 0) { result = GetDefaultValueForType(type); } else { Type originalType = type; bool isPatchMode = TryGetInnerTypeForDelta(ref type); ODataDeserializer deserializer = _deserializerProvider.GetODataDeserializer(type); if (deserializer == null) { throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName); } ODataMessageReader oDataMessageReader = null; ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = true }; try { IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders); oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, _deserializerProvider.EdmModel); ODataDeserializerContext readContext = new ODataDeserializerContext { IsPatchMode = isPatchMode, Request = _request, Model = _model }; if (isPatchMode) { readContext.PatchEntityType = originalType; } result = deserializer.Read(oDataMessageReader, readContext); } catch (Exception e) { if (formatterLogger == null) { throw; } formatterLogger.LogError(String.Empty, e); result = GetDefaultValueForType(type); } finally { if (oDataMessageReader != null) { oDataMessageReader.Dispose(); } } } return result; })); }
public static ODataMaterializer CreateMaterializerForMessage(IODataResponseMessage responseMessage, System.Data.Services.Client.ResponseInfo responseInfo, Type materializerType, QueryComponents queryComponents, ProjectionPlan plan, ODataPayloadKind payloadKind) { ODataMaterializer materializer2; bool projectionQuery = (plan != null) || (queryComponents.Projection != null); ODataMessageReader messageReader = CreateODataMessageReader(responseMessage, responseInfo, projectionQuery, ref payloadKind); IEdmType expectedType = null; try { ODataMaterializer materializer; if (materializerType != typeof(object)) { expectedType = ClientEdmModel.GetModel(responseInfo.MaxProtocolVersion).GetOrCreateEdmType(materializerType); } if ((payloadKind == ODataPayloadKind.Entry) || (payloadKind == ODataPayloadKind.Feed)) { if ((expectedType != null) && (expectedType.TypeKind != EdmTypeKind.Entity)) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidNonEntityType(materializerType.FullName)); } ODataReader reader = CreateODataReader(messageReader, payloadKind, expectedType, responseInfo.MaxProtocolVersion); materializer = new ODataReaderEntityMaterializer(messageReader, reader, responseInfo, queryComponents, materializerType, plan); } else { switch (payloadKind) { case ODataPayloadKind.Property: if ((expectedType != null) && (expectedType.TypeKind == EdmTypeKind.Entity)) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidEntityType(materializerType.FullName)); } break; case ODataPayloadKind.EntityReferenceLink: case ODataPayloadKind.EntityReferenceLinks: materializer = new ODataLinksMaterializer(messageReader, responseInfo, materializerType, queryComponents.SingleResult); goto Label_013A; case ODataPayloadKind.Value: materializer = new ODataValueMaterializer(messageReader, responseInfo, materializerType, queryComponents.SingleResult); goto Label_013A; case ODataPayloadKind.BinaryValue: case ODataPayloadKind.Collection: case ODataPayloadKind.ServiceDocument: case ODataPayloadKind.MetadataDocument: goto Label_0129; case ODataPayloadKind.Error: { ODataError error = messageReader.ReadError(); throw new ODataErrorException(error.Message, error); } default: goto Label_0129; } materializer = new ODataPropertyMaterializer(messageReader, responseInfo, materializerType, queryComponents.SingleResult); } goto Label_013A; Label_0129: throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidResponsePayload(responseInfo.DataNamespace)); Label_013A: materializer2 = materializer; } catch (Exception exception) { if (CommonUtil.IsCatchableExceptionType(exception)) { messageReader.Dispose(); } throw; } return(materializer2); }