/// <summary> /// Writes an entity reference link. /// </summary> /// <param name="binding">The link descriptor.</param> /// <param name="requestMessage">The request message used for writing the payload.</param> internal void WriteEntityReferenceLink(LinkDescriptor binding, ODataRequestMessageWrapper requestMessage) #endif { using (ODataMessageWriter messageWriter = Serializer.CreateMessageWriter(requestMessage, this.requestInfo, false /*isParameterPayload*/)) { EntityDescriptor targetResource = this.requestInfo.EntityTracker.GetEntityDescriptor(binding.Target); Uri targetResourceEditLink; if (null != targetResource.GetLatestIdentity()) { // When we write the uri in the payload, we need to make sure that we write the edit // link in the payload, since the request uri is the edit link of the parent entity. // Think of a read/write service - since the uri is the target link to the parent entity // its better that we write the edit link of the child entity in the payload. targetResourceEditLink = targetResource.GetResourceUri(this.requestInfo.BaseUriResolver, false /*queryLink*/); } else { #if DEBUG Debug.Assert(isBatch, "we should be cross-referencing entities only in batch scenarios"); #endif targetResourceEditLink = UriUtil.CreateUri("$" + targetResource.ChangeOrder.ToString(CultureInfo.InvariantCulture), UriKind.Relative); } ODataEntityReferenceLink referenceLink = new ODataEntityReferenceLink(); referenceLink.Url = targetResourceEditLink; messageWriter.WriteEntityReferenceLink(referenceLink); } }
/// <summary> /// Write the entry element. /// </summary> /// <param name="entityDescriptor">The entity.</param> /// <param name="relatedLinks">Collection of links related to the entity.</param> /// <param name="requestMessage">The OData request message.</param> internal void WriteEntry(EntityDescriptor entityDescriptor, IEnumerable <LinkDescriptor> relatedLinks, ODataRequestMessageWrapper requestMessage) { ClientEdmModel model = this.requestInfo.Model; ClientTypeAnnotation entityType = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType())); using (ODataMessageWriter messageWriter = Serializer.CreateMessageWriter(requestMessage, this.requestInfo, false /*isParameterPayload*/)) { ODataWriterWrapper entryWriter = ODataWriterWrapper.CreateForEntry(messageWriter, this.requestInfo.Configurations.RequestPipeline); // Get the server type name using the type resolver or from the entity descriptor string serverTypeName = this.requestInfo.GetServerTypeName(entityDescriptor); var entry = CreateODataEntry(entityDescriptor, serverTypeName, entityType, this.requestInfo.Format); // Add the annotation required for writing the payload into an XElement // for firing WritingEntity events if (this.requestInfo.HasWritingEventHandlers) { entry.SetAnnotation(new WritingEntityInfo(entityDescriptor.Entity, this.requestInfo)); } if (serverTypeName == null) { serverTypeName = this.requestInfo.InferServerTypeNameFromServerModel(entityDescriptor); } entry.Properties = this.propertyConverter.PopulateProperties(entityDescriptor.Entity, serverTypeName, entityType.PropertiesToSerialize()); entryWriter.WriteStart(entry, entityDescriptor.Entity); if (EntityStates.Added == entityDescriptor.State) { this.WriteNavigationLink(entityDescriptor, relatedLinks, entryWriter); } entryWriter.WriteEnd(entry, entityDescriptor.Entity); } }
private ODataRequestMessageWrapper GenerateBatchRequest() { if ((base.ChangedEntries.Count == 0) && (this.Queries == null)) { base.SetCompleted(); return(null); } ODataRequestMessageWrapper requestMessage = this.CreateBatchRequest(); using (ODataMessageWriter writer = Serializer.CreateMessageWriter(requestMessage, base.RequestInfo)) { ODataUtils.SetHeadersForPayload(writer, ODataPayloadKind.Batch); requestMessage.FireSendingRequest2(null); this.batchWriter = writer.CreateODataBatchWriter(); this.batchWriter.WriteStartBatch(); if (this.Queries != null) { for (int i = 0; i < this.Queries.Length; i++) { Uri requestUri = base.RequestInfo.BaseUriResolver.CreateAbsoluteUriIfNeeded(this.Queries[i].QueryComponents(base.RequestInfo.MaxProtocolVersion).Uri); ODataRequestMessageWrapper wrapper2 = this.CreateRequestMessage(requestUri, "GET"); Version requestVersion = this.Queries[i].QueryComponents(base.RequestInfo.MaxProtocolVersion).Version; WebUtil.SetOperationVersionHeaders(wrapper2, requestVersion, base.RequestInfo.MaxProtocolVersionAsVersion); wrapper2.FireSendingRequest2(null); } } else if (0 < base.ChangedEntries.Count) { this.batchWriter.WriteStartChangeset(); ClientEdmModel model = ClientEdmModel.GetModel(base.RequestInfo.MaxProtocolVersion); for (int j = 0; j < base.ChangedEntries.Count; j++) { Descriptor descriptor = base.ChangedEntries[j]; if (!descriptor.ContentGeneratedForSave) { ODataRequestMessageWrapper wrapper3; EntityDescriptor entityDescriptor = descriptor as EntityDescriptor; if (descriptor.DescriptorKind == DescriptorKind.Entity) { if (entityDescriptor.State != EntityStates.Added) { if (((entityDescriptor.State == EntityStates.Unchanged) || (entityDescriptor.State == EntityStates.Modified)) && (entityDescriptor.SaveStream != null)) { throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BatchNotSupportedForMediaLink); } } else if (model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType())).IsMediaLinkEntry || entityDescriptor.IsMediaLinkEntry) { throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BatchNotSupportedForMediaLink); } } else if (descriptor.DescriptorKind == DescriptorKind.NamedStream) { throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BatchNotSupportedForNamedStreams); } if (descriptor.DescriptorKind == DescriptorKind.Entity) { wrapper3 = base.CreateRequest(entityDescriptor); } else { wrapper3 = base.CreateRequest((LinkDescriptor)descriptor); } wrapper3.FireSendingRequest2(descriptor); base.CreateChangeData(j, wrapper3); } } this.batchWriter.WriteEndChangeset(); } this.batchWriter.WriteEndBatch(); this.batchWriter.Flush(); } return(requestMessage); }
/// <summary> /// Writes the body operation parameters associated with a ServiceAction. /// </summary> /// <param name="operationParameters">The list of operation parameters to write.</param> /// <param name="requestMessage">The OData request message used to write the operation parameters.</param> internal void WriteBodyOperationParameters(List <BodyOperationParameter> operationParameters, ODataRequestMessageWrapper requestMessage) { Debug.Assert(requestMessage != null, "requestMessage != null"); Debug.Assert(operationParameters != null, "operationParameters != null"); Debug.Assert(operationParameters.Any(), "operationParameters.Any()"); using (ODataMessageWriter messageWriter = Serializer.CreateMessageWriter(requestMessage, this.requestInfo, true /*isParameterPayload*/)) { ODataParameterWriter parameterWriter = messageWriter.CreateODataParameterWriter(null); parameterWriter.WriteStart(); foreach (OperationParameter operationParameter in operationParameters) { if (operationParameter.Value == null) { parameterWriter.WriteValue(operationParameter.Name, operationParameter.Value); } else { ClientEdmModel model = this.requestInfo.Model; IEdmType edmType = model.GetOrCreateEdmType(operationParameter.Value.GetType()); Debug.Assert(edmType != null, "edmType != null"); switch (edmType.TypeKind) { case EdmTypeKind.Collection: { Collections.IEnumerator enumerator = ((ICollection)operationParameter.Value).GetEnumerator(); ODataCollectionWriter collectionWriter = parameterWriter.CreateCollectionWriter(operationParameter.Name); ODataCollectionStart odataCollectionStart = new ODataCollectionStart(); collectionWriter.WriteStart(odataCollectionStart); while (enumerator.MoveNext()) { Object collectionItem = enumerator.Current; if (collectionItem == null) { throw new NotSupportedException(Strings.Serializer_NullCollectionParamterItemValue(operationParameter.Name)); } IEdmType edmItemType = model.GetOrCreateEdmType(collectionItem.GetType()); Debug.Assert(edmItemType != null, "edmItemType != null"); switch (edmItemType.TypeKind) { case EdmTypeKind.Complex: { Debug.Assert(model.GetClientTypeAnnotation(edmItemType).ElementType != null, "edmItemType.GetClientTypeAnnotation().ElementType != null"); ODataComplexValue complexValue = this.propertyConverter.CreateODataComplexValue( model.GetClientTypeAnnotation(edmItemType).ElementType, collectionItem, null /*propertyName*/, false /*isCollectionItem*/, null /*visitedComplexTypeObjects*/); Debug.Assert(complexValue != null, "complexValue != null"); collectionWriter.WriteItem(complexValue); break; } case EdmTypeKind.Primitive: { collectionWriter.WriteItem(collectionItem); break; } default: // EdmTypeKind.Entity // EdmTypeKind.Row // EdmTypeKind.EntityReference // EdmTypeKind.Enum. throw new NotSupportedException(Strings.Serializer_InvalidCollectionParamterItemType(operationParameter.Name, edmItemType.TypeKind)); } } collectionWriter.WriteEnd(); collectionWriter.Flush(); break; } case EdmTypeKind.Complex: { Debug.Assert(model.GetClientTypeAnnotation(edmType).ElementType != null, "model.GetClientTypeAnnotation(edmType).ElementType != null"); ODataComplexValue complexValue = this.propertyConverter.CreateODataComplexValue( model.GetClientTypeAnnotation(edmType).ElementType, operationParameter.Value, null /*propertyName*/, false /*isCollectionItemType*/, null /*visitedComplexTypeObjects*/); Debug.Assert(complexValue != null, "complexValue != null"); parameterWriter.WriteValue(operationParameter.Name, complexValue); break; } case EdmTypeKind.Primitive: parameterWriter.WriteValue(operationParameter.Name, operationParameter.Value); break; default: // EdmTypeKind.Entity // EdmTypeKind.Row // EdmTypeKind.EntityReference // EdmTypeKind.Enum. throw new NotSupportedException(Strings.Serializer_InvalidParameterType(operationParameter.Name, edmType.TypeKind)); } } // else } // foreach parameterWriter.WriteEnd(); parameterWriter.Flush(); } }