Пример #1
0
        internal ODataEntriesEntityMaterializer CreateODataEntriesEntityMaterializer(
            List <ODataResource> resources,
            Type resourceType,
            TestMaterializerContext materializerContext = null)
        {
            var clientEdmModel = new ClientEdmModel(ODataProtocolVersion.V4);
            var context        = new DataServiceContext();

            var resourceSet = new ODataResourceSet();

            MaterializerFeed.CreateFeed(resourceSet, resources);
            resources.ForEach(r =>
            {
                if (r == null)
                {
                    MaterializerEntry.CreateEmpty();
                }
                else
                {
                    MaterializerEntry.CreateEntry(r, ODataFormat.Json, true, clientEdmModel);
                }
            });
            materializerContext = materializerContext ?? new TestMaterializerContext()
            {
                Model = clientEdmModel, Context = context
            };
            var             adapter    = new EntityTrackingAdapter(new TestEntityTracker(), MergeOption.OverwriteChanges, clientEdmModel, context);
            QueryComponents components = new QueryComponents(new Uri("http://foo.com/Service"), new Version(4, 0), resourceType, null, new Dictionary <Expression, Expression>());

            return(new ODataEntriesEntityMaterializer(resources, materializerContext, adapter, components, resourceType, null, ODataFormat.Json));
        }
Пример #2
0
        /// <summary>
        /// Creates the result object for the specified query parameters.
        /// </summary>
        /// <param name="source">The source object for the request.</param>
        /// <param name="context">The data service context.</param>
        /// <param name="callback">The AsyncCallback delegate.</param>
        /// <param name="state">The state object for the callback.</param>
        /// <param name="method">async method name at the source.</param>
        /// <returns>Result representing the create request. The request has not been initiated yet.</returns>
        private QueryResult CreateExecuteResult(object source, DataServiceContext context, AsyncCallback callback, object state, string method)
        {
            Debug.Assert(context != null, "context is null");

            QueryComponents qc          = this.QueryComponents(context.Model);
            RequestInfo     requestInfo = new RequestInfo(context);

            Debug.Assert(
                string.CompareOrdinal(XmlConstants.HttpMethodPost, qc.HttpMethod) == 0 ||
                string.CompareOrdinal(XmlConstants.HttpMethodGet, qc.HttpMethod) == 0 ||
                string.CompareOrdinal(XmlConstants.HttpMethodDelete, qc.HttpMethod) == 0,
                "Only get, post and delete are supported in the execute pipeline, which should have been caught earlier");

            if (qc.UriOperationParameters != null)
            {
                Debug.Assert(qc.UriOperationParameters.Any(), "qc.UriOperationParameters.Any()");
                Serializer serializer = new Serializer(requestInfo);
                this.RequestUri = serializer.WriteUriOperationParametersToUri(this.RequestUri, qc.UriOperationParameters);
            }

            HeaderCollection headers = new HeaderCollection();

            if (string.CompareOrdinal(XmlConstants.HttpMethodPost, qc.HttpMethod) == 0)
            {
                if (qc.BodyOperationParameters == null)
                {
                    // set the content length to be 0 if there are no operation parameters.
                    headers.SetHeader(XmlConstants.HttpContentLength, "0");
                }
                else
                {
                    context.Format.SetRequestContentTypeForOperationParameters(headers);
                }
            }

            // Validate and set the request DSV and MDSV header
            headers.SetRequestVersion(qc.Version, requestInfo.MaxProtocolVersionAsVersion);

            requestInfo.Format.SetRequestAcceptHeaderForQuery(headers, qc);

            // We currently do not have a descriptor to expose to the user for invoking something through Execute. Ideally we could expose an OperationDescriptor.
            ODataRequestMessageWrapper requestMessage = new RequestInfo(context).WriteHelper.CreateRequestMessage(context.CreateRequestArgsAndFireBuildingRequest(qc.HttpMethod, this.RequestUri, headers, context.HttpStack, null /*descriptor*/));

            requestMessage.FireSendingRequest2(null /*descriptor*/);

            if (qc.BodyOperationParameters != null)
            {
                Debug.Assert(string.CompareOrdinal(XmlConstants.HttpMethodPost, qc.HttpMethod) == 0, "qc.HttpMethod == XmlConstants.HttpMethodPost");
                Debug.Assert(qc.BodyOperationParameters.Any(), "unexpected body operation parameter count of zero.");

                Serializer serializer = new Serializer(requestInfo, context.EntityParameterSendOption);
                serializer.WriteBodyOperationParameters(qc.BodyOperationParameters, requestMessage);

                // pass in the request stream so that request payload can be written to the http webrequest.
                return(new QueryResult(source, method, this, requestMessage, requestInfo, callback, state, requestMessage.CachedRequestStream));
            }

            return(new QueryResult(source, method, this, requestMessage, requestInfo, callback, state));
        }
Пример #3
0
        /// <summary>Create a request for a specific Uri</summary>
        /// <param name="requestUri">The URI for the request.</param>
        /// <param name="queryComponents">The query components for the request</param>
        /// <param name="plan">Projection plan to reuse (possibly null).</param>
        internal DataServiceRequest(Uri requestUri, QueryComponents queryComponents, ProjectionPlan plan)
            : this(requestUri)
        {
            Debug.Assert(requestUri != null, "requestUri != null");
            Debug.Assert(queryComponents != null, "queryComponents != null");

            this.queryComponents = queryComponents;
            this.plan            = plan;
        }
Пример #4
0
        /// <summary>
        /// gets the query components for the query after translating
        /// </summary>
        /// <returns>QueryComponents for query</returns>
        private QueryComponents Translate()
        {
            if (this.queryComponents == null)
            {
                this.queryComponents = this.queryProvider.Translate(this.queryExpression);
            }

            return(this.queryComponents);
        }
Пример #5
0
        /// <summary>
        /// Synchronously executes the query and returns the value.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="parseQueryResultFunc">A function to process the query result.</param>
        /// <returns>The query result</returns>
        internal TElement GetValue <TElement>(DataServiceContext context, Func <QueryResult, TElement> parseQueryResultFunc)
        {
            Debug.Assert(context != null, "context is null");
            QueryComponents queryComponents = this.QueryComponents(context.Model);
            Version         requestVersion  = queryComponents.Version;

            if (requestVersion == null)
            {
                requestVersion = Util.ODataVersion4;
            }

            Uri requestUri = queryComponents.Uri;
            DataServiceRequest <TElement> serviceRequest = new DataServiceRequest <TElement>(requestUri, queryComponents, null);

            HeaderCollection headers = new HeaderCollection();

            // Validate and set the request DSV header
            headers.SetRequestVersion(requestVersion, context.MaxProtocolVersionAsVersion);
            context.Format.SetRequestAcceptHeaderForCount(headers);

            string httpMethod = XmlConstants.HttpMethodGet;
            ODataRequestMessageWrapper request = context.CreateODataRequestMessage(
                context.CreateRequestArgsAndFireBuildingRequest(httpMethod, requestUri, headers, context.HttpStack, null /*descriptor*/),
                null /*descriptor*/);

            QueryResult queryResult = new QueryResult(this, Util.ExecuteMethodName, serviceRequest, request, new RequestInfo(context), null, null);

            try
            {
                queryResult.ExecuteQuery();

                if (HttpStatusCode.NoContent != queryResult.StatusCode)
                {
                    TElement parsedResult = parseQueryResultFunc(queryResult);

                    return(parsedResult);
                }
                else
                {
                    throw new DataServiceQueryException(Strings.DataServiceRequest_FailGetValue, queryResult.Failure);
                }
            }
            catch (InvalidOperationException ex)
            {
                QueryOperationResponse operationResponse;
                operationResponse = queryResult.GetResponse <TElement>(MaterializeAtom.EmptyResults);
                if (operationResponse != null)
                {
                    operationResponse.Error = ex;
                    throw new DataServiceQueryException(Strings.DataServiceException_GeneralError, ex, operationResponse);
                }

                throw;
            }
        }
        private MaterializeAtom CreateMaterializer <T>(string content, string contentType, ProjectionPlan plan)
        {
            ResponseInfo                info    = new ResponseInfo(new RequestInfo(this.context), MergeOption.AppendOnly);
            QueryComponents             qc      = new QueryComponents(this.serviceUri, Util.ODataVersion4, typeof(T), null, null);
            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add(XmlConstants.HttpContentType, contentType);
            var bytes = System.Text.Encoding.UTF8.GetBytes(content);
            TestResponseMessage responseMessage = new TestResponseMessage(headers, HttpStatusCode.OK, () => new System.IO.MemoryStream(bytes));

            return(new MaterializeAtom(info, qc, plan, responseMessage, ODataPayloadKind.Unsupported));
        }
Пример #7
0
        private static ProjectionPlan CreatePlan(QueryComponents queryComponents)
        {
            LambdaExpression projection = queryComponents.Projection;

            if (projection == null)
            {
                return(CreatePlanForDirectMaterialization(queryComponents.LastSegmentType));
            }
            ProjectionPlan plan = ProjectionPlanCompiler.CompilePlan(projection, queryComponents.NormalizerRewrites);

            plan.LastSegmentType = queryComponents.LastSegmentType;
            return(plan);
        }
Пример #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataReaderEntityMaterializer" /> class.
 /// </summary>
 /// <param name="odataMessageReader">The odata message reader.</param>
 /// <param name="reader">The reader.</param>
 /// <param name="materializerContext">The materializer context.</param>
 /// <param name="entityTrackingAdapter">The entity tracking adapter.</param>
 /// <param name="queryComponents">The query components.</param>
 /// <param name="expectedType">The expected type.</param>
 /// <param name="materializeEntryPlan">The materialize entry plan.</param>
 public ODataReaderEntityMaterializer(
     ODataMessageReader odataMessageReader,
     ODataReaderWrapper reader,
     IODataMaterializerContext materializerContext,
     EntityTrackingAdapter entityTrackingAdapter,
     QueryComponents queryComponents,
     Type expectedType,
     ProjectionPlan materializeEntryPlan)
     : base(materializerContext, entityTrackingAdapter, queryComponents, expectedType, materializeEntryPlan)
 {
     this.messageReader    = odataMessageReader;
     this.feedEntryAdapter = new FeedAndEntryMaterializerAdapter(odataMessageReader, reader, materializerContext.Model, entityTrackingAdapter.MergeOption);
 }
Пример #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataEntriesEntityMaterializer" /> class.
 /// </summary>
 /// <param name="entries">The entries.</param>
 /// <param name="materializerContext">The materializer context.</param>
 /// <param name="entityTrackingAdapter">The entity tracking adapter.</param>
 /// <param name="queryComponents">The query components.</param>
 /// <param name="expectedType">The expected type.</param>
 /// <param name="materializeEntryPlan">The materialize entry plan.</param>
 /// <param name="format">The format.</param>
 public ODataEntriesEntityMaterializer(
     IEnumerable <ODataEntry> entries,
     IODataMaterializerContext materializerContext,
     EntityTrackingAdapter entityTrackingAdapter,
     QueryComponents queryComponents,
     Type expectedType,
     ProjectionPlan materializeEntryPlan,
     ODataFormat format)
     : base(materializerContext, entityTrackingAdapter, queryComponents, expectedType, materializeEntryPlan)
 {
     this.format      = format;
     this.feedEntries = entries.GetEnumerator();
 }
Пример #10
0
        /// <summary>The QueryComponents associated with this request</summary>
        /// <param name="model">The client model.</param>
        /// <returns>an instance of QueryComponents.</returns>
        internal override QueryComponents QueryComponents(ClientEdmModel model)
        {
            if (this.queryComponents == null)
            {
                Type elementType = typeof(TElement);

                // for 1..* navigation properties we need the type of the entity of the collection that is being navigated to. Otherwise we use TElement.
                elementType          = PrimitiveType.IsKnownType(elementType) || WebUtil.IsCLRTypeCollection(elementType, model) ? elementType : TypeSystem.GetElementType(elementType);
                this.queryComponents = new QueryComponents(this.requestUri, Util.ODataVersionEmpty, elementType, null, null);
            }

            return(this.queryComponents);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataLoadNavigationPropertyMaterializer" /> class.
 /// </summary>
 /// <param name="odataMessageReader">The odata message reader.</param>
 /// <param name="reader">The reader.</param>
 /// <param name="materializerContext">The materializer context.</param>
 /// <param name="entityTrackingAdapter">The entity tracking adapter.</param>
 /// <param name="queryComponents">The query components.</param>
 /// <param name="expectedType">The expected type.</param>
 /// <param name="materializeEntryPlan">The materialize entry plan.</param>
 /// <param name="responseInfo">LoadProperty Response Info object.</param>
 public ODataLoadNavigationPropertyMaterializer(
     ODataMessageReader odataMessageReader,
     ODataReaderWrapper reader,
     IODataMaterializerContext materializerContext,
     EntityTrackingAdapter entityTrackingAdapter,
     QueryComponents queryComponents,
     Type expectedType,
     ProjectionPlan materializeEntryPlan,
     LoadPropertyResponseInfo responseInfo)
     : base(odataMessageReader, reader, materializerContext, entityTrackingAdapter, queryComponents, expectedType, materializeEntryPlan)
 {
     this.responseInfo = responseInfo;
     this.items        = new List <object>();
 }
Пример #12
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="responseInfo">originating context</param>
        /// <param name="entries">entries that needs to be materialized.</param>
        /// <param name="elementType">result type.</param>
        /// <param name="format">The format of the response being materialized from.</param>
        internal MaterializeAtom(ResponseInfo responseInfo, IEnumerable <ODataResource> entries, Type elementType, ODataFormat format)
        {
            this.responseInfo            = responseInfo;
            this.elementType             = elementType;
            this.expectingPrimitiveValue = PrimitiveType.IsKnownNullableType(elementType);

            Type                     implementationType;
            Type                     materializerType = GetTypeForMaterializer(this.expectingPrimitiveValue, this.elementType, responseInfo.Model, out implementationType);
            QueryComponents          qc      = new QueryComponents(null, Util.ODataVersionEmpty, elementType, null, null);
            ODataMaterializerContext context = new ODataMaterializerContext(responseInfo);
            EntityTrackingAdapter    entityTrackingAdapter = new EntityTrackingAdapter(responseInfo.EntityTracker, responseInfo.MergeOption, responseInfo.Model, responseInfo.Context);

            this.materializer = new ODataEntriesEntityMaterializer(entries, context, entityTrackingAdapter, qc, materializerType, null, format);
        }
Пример #13
0
        public void Continuation_Creates_Incorrect_DataServiceVersion()
        {
            // Regression test for:Client always sends DSV=2.0 when following a continuation token
            ProjectionPlan plan = new ProjectionPlan()
            {
                LastSegmentType = typeof(int),
                ProjectedType   = typeof(int)
            };

            var             continuationToken = DataServiceQueryContinuation.Create(new Uri("http://localhost/Set?$skiptoken='Me'"), plan);
            QueryComponents queryComponents   = continuationToken.CreateQueryComponents();

            Assert.AreSame(queryComponents.Version, Util.ODataVersionEmpty, "OData-Version of  query components should be empty for Continuation token");
        }
Пример #14
0
        private MaterializeAtom CreateMaterializer <T>(Uri requestUri, string content, string contentType, ODataPayloadKind payloadKind)
        {
            DataServiceContext ctx = new DataServiceContext(new Uri("http://localhost"), Microsoft.OData.Client.ODataProtocolVersion.V4);

            ctx.EnableAtom = true;
            ResponseInfo    info    = new ResponseInfo(new RequestInfo(ctx), MergeOption.AppendOnly);
            QueryComponents qc      = new QueryComponents(requestUri, Util.ODataVersion4, typeof(T), null, null);
            var             headers = new HeaderCollection();

            headers.SetHeader("Content-Type", contentType);
            var bytes = System.Text.UTF8Encoding.UTF8.GetBytes(content);
            HttpWebResponseMessage responseMessage = new HttpWebResponseMessage(headers, (int)System.Net.HttpStatusCode.OK, () => new System.IO.MemoryStream(bytes));

            return(new MaterializeAtom(info, qc, null, responseMessage, payloadKind));
        }
Пример #15
0
        /// <summary>
        /// get an enumerable materializes the objects the response
        /// </summary>
        /// <param name="responseInfo">context</param>
        /// <param name="queryComponents">query components</param>
        /// <param name="plan">Projection plan (if compiled in an earlier query).</param>
        /// <param name="contentType">contentType</param>
        /// <param name="message">the message</param>
        /// <param name="expectedPayloadKind">expected payload kind.</param>
        /// <returns>atom materializer</returns>
        internal static MaterializeAtom Materialize(
            ResponseInfo responseInfo,
            QueryComponents queryComponents,
            ProjectionPlan plan,
            string contentType,
            IODataResponseMessage message,
            ODataPayloadKind expectedPayloadKind)
        {
            Debug.Assert(queryComponents != null, "querycomponents");
            Debug.Assert(message != null, "message");

            // If there is no content (For e.g. /Customers(1)/BestFriend is null), we need to return empty results.
            if (message.StatusCode == (int)HttpStatusCode.NoContent || String.IsNullOrEmpty(contentType))
            {
                return(MaterializeAtom.EmptyResults);
            }

            return(new MaterializeAtom(responseInfo, queryComponents, plan, message, expectedPayloadKind));
        }
Пример #16
0
#pragma warning restore 649
#endif

        #endregion Private fields

        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="responseInfo">originating context</param>
        /// <param name="queryComponents">Query components (projection, expected type)</param>
        /// <param name="plan">Projection plan (if compiled in an earlier query).</param>
        /// <param name="responseMessage">responseMessage</param>
        /// <param name="payloadKind">The kind of the payload to materialize.</param>
        internal MaterializeAtom(
            ResponseInfo responseInfo,
            QueryComponents queryComponents,
            ProjectionPlan plan,
            IODataResponseMessage responseMessage,
            ODataPayloadKind payloadKind)
        {
            Debug.Assert(queryComponents != null, "queryComponents != null");

            this.responseInfo            = responseInfo;
            this.elementType             = queryComponents.LastSegmentType;
            this.expectingPrimitiveValue = PrimitiveType.IsKnownNullableType(elementType);

            Debug.Assert(responseMessage != null, "Response message is null! Did you mean to use Materializer.ResultsWrapper/EmptyResults?");

            Type implementationType;
            Type materializerType = GetTypeForMaterializer(this.expectingPrimitiveValue, this.elementType, responseInfo.Model, out implementationType);

            this.materializer = ODataMaterializer.CreateMaterializerForMessage(responseMessage, responseInfo, materializerType, queryComponents, plan, payloadKind);
        }
        public void ShortIntegrationTestToValidateEntryShouldBeRead()
        {
            var odataEntry = new ODataResource()
            {
                Id = new Uri("http://services.odata.org/OData/OData.svc/Customers(0)")
            };

            odataEntry.Properties = new ODataProperty[] { new ODataProperty()
                                                          {
                                                              Name = "ID", Value = 0
                                                          }, new ODataProperty()
                                                          {
                                                              Name = "Description", Value = "Simple Stuff"
                                                          } };

            var clientEdmModel = new ClientEdmModel(ODataProtocolVersion.V4);
            var context        = new DataServiceContext();

            MaterializerEntry.CreateEntry(odataEntry, ODataFormat.Json, true, clientEdmModel);
            var materializerContext = new TestMaterializerContext()
            {
                Model = clientEdmModel, Context = context
            };
            var             adapter    = new EntityTrackingAdapter(new TestEntityTracker(), MergeOption.OverwriteChanges, clientEdmModel, context);
            QueryComponents components = new QueryComponents(new Uri("http://foo.com/Service"), new Version(4, 0), typeof(Customer), null, new Dictionary <Expression, Expression>());

            var entriesMaterializer = new ODataEntriesEntityMaterializer(new ODataResource[] { odataEntry }, materializerContext, adapter, components, typeof(Customer), null, ODataFormat.Json);

            var customersRead = new List <Customer>();

            // This line will call ODataEntityMaterializer.ReadImplementation() which will reconstruct the entity, and will get non-public setter called.
            while (entriesMaterializer.Read())
            {
                customersRead.Add(entriesMaterializer.CurrentValue as Customer);
            }

            customersRead.Should().HaveCount(1);
            customersRead[0].ID.Should().Be(0);
            customersRead[0].Description.Should().Be("Simple Stuff");
        }
Пример #18
0
        /// <summary>
        /// Creates an instance of <see cref="MaterializeAtom"/> for the given plan.
        /// </summary>
        /// <param name="plan">The projection plan.</param>
        /// <param name="payloadKind">expected payload kind.</param>
        /// <returns>A new materializer instance</returns>
        private MaterializeAtom CreateMaterializer(ProjectionPlan plan, ODataPayloadKind payloadKind)
        {
            QueryComponents queryComponents = this.ServiceRequest.QueryComponents(this.responseInfo.Model);

            // In V2, in projection path, we did not check for assignability between the expected type and the type returned by the type resolver.
            if (plan != null || queryComponents.Projection != null)
            {
                this.RequestInfo.TypeResolver.IsProjectionRequest();
            }

            var responseMessageWrapper = new HttpWebResponseMessage(
                new HeaderCollection(this.responseMessage),
                this.responseMessage.StatusCode,
                this.GetResponseStream);

            return(DataServiceRequest.Materialize(
                       this.responseInfo,
                       queryComponents,
                       plan,
                       this.ContentType,
                       responseMessageWrapper,
                       payloadKind));
        }
Пример #19
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;
            }
        }
Пример #20
0
 public ODataReaderEntityMaterializer(ODataMessageReader odataMessageReader, ODataReader reader, ResponseInfo responseInfo, QueryComponents queryComponents, Type expectedType, ProjectionPlan materializeEntryPlan) : base(responseInfo, queryComponents, expectedType, materializeEntryPlan)
 {
     this.messageReader = odataMessageReader;
     this.itemReader    = new ODataFeedOrEntryReader(reader, responseInfo);
 }
 public ODataEntriesEntityMaterializer(IEnumerable <ODataEntry> entries, ResponseInfo responseInfo, QueryComponents queryComponents, Type expectedType, ProjectionPlan materializeEntryPlan) : base(responseInfo, queryComponents, expectedType, materializeEntryPlan)
 {
     this.feedEntries = entries.GetEnumerator();
 }
Пример #22
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);
        }
Пример #23
0
 public ODataEntityMaterializer(ResponseInfo responseInfo, QueryComponents queryComponents, Type expectedType, ProjectionPlan materializeEntryPlan) : base(responseInfo, expectedType)
 {
     this.materializeEntryPlan = materializeEntryPlan ?? CreatePlan(queryComponents);
     this.mergeOption          = base.ResponseInfo.MergeOption;
     this.log = new AtomMaterializerLog(base.ResponseInfo);
 }
Пример #24
0
        public void MaterializeEntityShouldWork()
        {
            var odataEntry = new OData.ODataResource()
            {
                Id = new Uri("http://www.odata.org/service.svc/entitySet(1)")
            };

            odataEntry.Properties = new OData.ODataProperty[]
            {
                new OData.ODataProperty {
                    Name = "keyProp", Value = 1
                },
                new OData.ODataProperty {
                    Name = "colorProp", Value = new OData.ODataEnumValue("blue")
                },
                new OData.ODataProperty {
                    Name  = "primitiveCollection",
                    Value = new OData.ODataCollectionValue
                    {
                        TypeName = "Edm.Int32",
                        Items    = new List <object> {
                            1, 2, 3
                        }
                    }
                },
                new OData.ODataProperty {
                    Name  = "enumCollection",
                    Value = new OData.ODataCollectionValue
                    {
                        TypeName = "color",
                        Items    = new List <OData.ODataEnumValue> {
                            new OData.ODataEnumValue("white"), new OData.ODataEnumValue("blue")
                        }
                    }
                }
            };

            var complexP = new OData.ODataNestedResourceInfo()
            {
                Name         = "complexProp",
                IsCollection = false
            };

            var complexResource = new OData.ODataResource
            {
                Properties = new OData.ODataProperty[]
                {
                    new OData.ODataProperty {
                        Name = "age", Value = 11
                    },
                    new OData.ODataProperty {
                        Name = "name", Value = "June"
                    }
                }
            };

            var complexColP = new OData.ODataNestedResourceInfo
            {
                Name         = "complexCollection",
                IsCollection = true
            };

            var complexColResourceSet = new OData.ODataResourceSet();

            var items = new List <OData.ODataResource>
            {
                new OData.ODataResource
                {
                    Properties = new OData.ODataProperty[]
                    {
                        new OData.ODataProperty {
                            Name = "name", Value = "Aug"
                        },
                        new OData.ODataProperty {
                            Name = "age", Value = 8
                        },
                        new OData.ODataProperty {
                            Name = "color", Value = new OData.ODataEnumValue("white")
                        }
                    }
                },
                new OData.ODataResource
                {
                    Properties = new OData.ODataProperty[]
                    {
                        new OData.ODataProperty {
                            Name = "name", Value = "Sep"
                        },
                        new OData.ODataProperty {
                            Name = "age", Value = 9
                        },
                        new OData.ODataProperty {
                            Name = "color", Value = new OData.ODataEnumValue("blue")
                        }
                    }
                }
            };

            var clientEdmModel    = new ClientEdmModel(ODataProtocolVersion.V4);
            var context           = new DataServiceContext();
            var materializerEntry = MaterializerEntry.CreateEntry(odataEntry, OData.ODataFormat.Json, true, clientEdmModel);

            MaterializerNavigationLink.CreateLink(complexP, MaterializerEntry.CreateEntry(complexResource, OData.ODataFormat.Json, true, clientEdmModel));
            MaterializerFeed.CreateFeed(complexColResourceSet, items);
            MaterializerNavigationLink.CreateLink(complexColP, complexColResourceSet);

            var materializerContext = new TestMaterializerContext()
            {
                Model = clientEdmModel, Context = context
            };
            var             adapter    = new EntityTrackingAdapter(new TestEntityTracker(), MergeOption.OverwriteChanges, clientEdmModel, context);
            QueryComponents components = new QueryComponents(new Uri("http://foo.com/Service"), new Version(4, 0), typeof(EntityType), null, new Dictionary <Expression, Expression>());

            var entriesMaterializer = new ODataEntriesEntityMaterializer(new OData.ODataResource[] { odataEntry }, materializerContext, adapter, components, typeof(EntityType), null, OData.ODataFormat.Json);

            var customersRead = new List <EntityType>();

            while (entriesMaterializer.Read())
            {
                customersRead.Add(entriesMaterializer.CurrentValue as EntityType);
            }

            customersRead.Should().HaveCount(1);
            customersRead[0].KeyProp.Should().Be(1);
            customersRead[0].ComplexProp.Should().Equals(new ComplexType {
                Age = 11, Name = "June"
            });
            customersRead[0].ColorProp.Should().Equals(Color.Blue);
            customersRead[0].PrimitiveCollection.Should().Equals(new List <int> {
                1, 2, 3
            });
            ComplexType complex1 = new ComplexType {
                Name = "Aug", Age = 8, Color = Color.White
            };
            ComplexType complex2 = new ComplexType {
                Name = "Sep", Age = 9, Color = Color.Blue
            };

            customersRead[0].ComplexCollection.Should().Equals(new List <ComplexType> {
                complex1, complex2
            });
            customersRead[0].EnumCollection.Should().Equals(new List <Color> {
                Color.White, Color.Blue
            });
        }
 /// <summary>
 /// Sets the value of the Accept header for a query.
 /// </summary>
 /// <param name="headers">The headers to modify.</param>
 /// <param name="components">The query components for the request.</param>
 internal void SetRequestAcceptHeaderForQuery(HeaderCollection headers, QueryComponents components)
 {
     this.SetAcceptHeaderAndCharset(headers, ChooseMediaType(components.HasSelectQueryOption));
 }
Пример #26
0
        /// <summary>
        /// execute uri and materialize result
        /// </summary>
        /// <typeparam name="TElement">element type</typeparam>
        /// <param name="context">context</param>
        /// <param name="queryComponents">query components for request to execute</param>
        /// <returns>enumerable of results</returns>
        internal QueryOperationResponse <TElement> Execute <TElement>(DataServiceContext context, QueryComponents queryComponents)
        {
            QueryResult result = null;

            try
            {
                Uri requestUri = queryComponents.Uri;
                DataServiceRequest <TElement> serviceRequest = new DataServiceRequest <TElement>(requestUri, queryComponents, this.Plan);
                result = serviceRequest.CreateExecuteResult(this, context, null, null, Util.ExecuteMethodName);
                result.ExecuteQuery();
                return(result.ProcessResult <TElement>(this.Plan));
            }
            catch (InvalidOperationException ex)
            {
                if (result != null)
                {
                    QueryOperationResponse operationResponse = result.GetResponse <TElement>(MaterializeAtom.EmptyResults);

                    if (operationResponse != null)
                    {
                        if (context.IgnoreResourceNotFoundException)
                        {
                            DataServiceClientException cex = ex as DataServiceClientException;
                            if (cex != null && cex.StatusCode == (int)HttpStatusCode.NotFound)
                            {
                                // don't throw
                                return((QueryOperationResponse <TElement>)operationResponse);
                            }
                        }

                        operationResponse.Error = ex;
                        throw new DataServiceQueryException(Strings.DataServiceException_GeneralError, ex, operationResponse);
                    }
                }

                throw;
            }
        }