/// <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;
            });
        }
Esempio n. 3
0
        /// <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;
            }));
        }
Esempio n. 6
0
        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);
        }