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)); }
/// <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)); }
/// <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; }
/// <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); }
/// <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)); }
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); }
/// <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); }
/// <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(); }
/// <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>(); }
/// <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); }
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"); }
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)); }
/// <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)); }
#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"); }
/// <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)); }
/// <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; } }
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(); }
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); }
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); }
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)); }
/// <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; } }