/// <summary> /// Tracks the DeleteLink method. /// </summary> /// <param name="data">The data service context data on which to apply state transition.</param> /// <param name="source">The source.</param> /// <param name="sourcePropertyName">Name of the source property.</param> /// <param name="target">The target.</param> public static void TrackDeleteLink(this DataServiceContextData data, object source, string sourcePropertyName, object target) { EntityDescriptorData sourceDescriptorData = GetTrackedEntityDescriptorData(data, source, "Cannot delete link:", "source"); EntityDescriptorData targetDescriptorData = GetTrackedEntityDescriptorData(data, target, "Cannot delete link:", "target"); LinkDescriptorData descriptorData; if (data.TryGetLinkDescriptorData(sourceDescriptorData, sourcePropertyName, targetDescriptorData, out descriptorData) && descriptorData.State == EntityStates.Added) { data.RemoveDescriptorData(descriptorData); } else { CheckStateIsNot(EntityStates.Added, sourceDescriptorData, "Cannot delete link:", "source"); CheckStateIsNot(EntityStates.Added, targetDescriptorData, "Cannot delete link:", "target"); if (descriptorData == null) { data.CreateLinkDescriptorData(EntityStates.Deleted, data.GetNextChangeOrder(), sourceDescriptorData, sourcePropertyName, targetDescriptorData); } else if (descriptorData.State != EntityStates.Deleted) { data.ChangeStateAndChangeOrder(descriptorData, EntityStates.Deleted, data.GetNextChangeOrder()); } } }
/// <summary> /// Tracks the AttachLink method. /// </summary> /// <param name="data">The data service context data on which to apply state transition.</param> /// <param name="source">The source.</param> /// <param name="sourcePropertyName">Name of the source property.</param> /// <param name="target">The target.</param> public static void TrackAttachLink(this DataServiceContextData data, object source, string sourcePropertyName, object target) { ExceptionUtilities.CheckArgumentNotNull(data, "data"); LinkDescriptorData linkDescriptorData; if (data.TryGetLinkDescriptorData(source, sourcePropertyName, target, out linkDescriptorData)) { throw new TaupoInvalidOperationException( string.Format(CultureInfo.InvariantCulture, "The link already exists: {0}.", linkDescriptorData.ToString())); } EntityDescriptorData sourceDescriptorData = GetTrackedEntityDescriptorData(data, source, "Cannot attach link:", "source"); CheckStateIsNot(EntityStates.Deleted, sourceDescriptorData, "Cannot attach link:", "source"); CheckStateIsNot(EntityStates.Added, sourceDescriptorData, "Cannot attach link:", "source"); EntityDescriptorData targetDescriptorData = null; if (target != null) { targetDescriptorData = GetTrackedEntityDescriptorData(data, target, "Cannot attach link:", "target"); CheckStateIsNot(EntityStates.Deleted, targetDescriptorData, "Cannot attach link:", "target"); CheckStateIsNot(EntityStates.Added, targetDescriptorData, "Cannot attach link:", "target"); } data.CreateLinkDescriptorData(EntityStates.Unchanged, data.GetNextChangeOrder(), sourceDescriptorData, sourcePropertyName, targetDescriptorData); }
internal static Uri GetEntityInsertUri(DataServiceContextData contextData, EntityDescriptorData entityDescriptorData) { Uri insertUri; if (entityDescriptorData.InsertLink != null) { insertUri = entityDescriptorData.InsertLink; } else { ExceptionUtilities.CheckObjectNotNull(entityDescriptorData.ParentForInsert, "Entity descriptor data did not have insert link or parent for insert: {0}", entityDescriptorData); ExceptionUtilities.CheckObjectNotNull(entityDescriptorData.ParentPropertyForInsert, "Entity descriptor data did not have insert link or parent property for insert: {0}", entityDescriptorData); var parentDescriptor = contextData.GetEntityDescriptorData(entityDescriptorData.ParentForInsert); var linkInfo = parentDescriptor.LinkInfos.SingleOrDefault(l => l.Name == entityDescriptorData.ParentPropertyForInsert); if (linkInfo != null && linkInfo.NavigationLink != null) { insertUri = linkInfo.NavigationLink; } else { insertUri = new Uri(UriHelpers.ConcatenateUriSegments(parentDescriptor.EditLink.OriginalString, entityDescriptorData.ParentPropertyForInsert), UriKind.RelativeOrAbsolute); if (!insertUri.IsAbsoluteUri && contextData.BaseUri != null) { insertUri = new Uri(contextData.BaseUri, insertUri); } } } return(insertUri); }
/// <summary> /// Calculates the DataServiceVersion for a particular EntityDescriptor /// </summary> /// <param name="entityDescriptorData">Entity Descriptor Data</param> /// <param name="maxProtocolVersion">The client's max protocol version</param> /// <returns>A Data service protocol version</returns> public DataServiceProtocolVersion CalculateDataServiceVersion(EntityDescriptorData entityDescriptorData, DataServiceProtocolVersion maxProtocolVersion) { ExceptionUtilities.CheckArgumentNotNull(entityDescriptorData, "entityDescriptorData"); Type entityType = entityDescriptorData.Entity.GetType(); EntityType testEntityType = this.entityModelSchema.EntityTypes.Single(et => et.FullName == entityType.FullName); // Calculate expected version based on type's feed mappings. DataServiceProtocolVersion expectedVersion = VersionHelper.CalculateEntityPropertyMappingProtocolVersion(testEntityType, VersionCalculationType.Response, MimeTypes.ApplicationAtomXml, maxProtocolVersion, maxProtocolVersion); // Commenting out this code pending a quick versioning discussion with pratikp and ahmed // Cannot check in as with code it breaks BVT's, want to get this in and update pending discussion 12-7-10 // if (testEntityType.AllProperties.Any(p => p.IsStream())) // { // expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, DataServiceProtocolVersion.V4); // } // If there are bag properties then its at least v3 if (testEntityType.HasMultiValue(true) || testEntityType.HasSpatialProperties()) { expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, DataServiceProtocolVersion.V4); } return(expectedVersion); }
private HttpRequestData CreateDeleteRequest(EntityDescriptorData entityDescriptorData) { return(new HttpRequestData() { Verb = HttpVerb.Delete, Uri = entityDescriptorData.EditLink, }); }
/// <summary> /// Creates EntityChangeData which captures the state of the specified entity descriptor data. /// </summary> /// <param name="entityDescriptorData">The entity descriptor data.</param> /// <param name="propertiesValues">The properties values before SaveChanges.</param> /// <returns>Entity change data.</returns> public static ChangeData Create(EntityDescriptorData entityDescriptorData, IEnumerable <NamedValue> propertiesValues) { EntityChangeData changeData = new EntityChangeData(entityDescriptorData); foreach (NamedValue nv in propertiesValues) { changeData.CachedPropertiesValues.Add(nv.Name, nv.Value); } changeData.ClrTypeForRequery = entityDescriptorData.EntityClrType; return(changeData); }
private void VerifyDescriptor(DescriptorData expected, Descriptor actual, int responseOrder) { EntityDescriptorData entityDescriptorData = expected as EntityDescriptorData; LinkDescriptorData linkDescriptorData = expected as LinkDescriptorData; StreamDescriptorData streamDescriptorData = expected as StreamDescriptorData; if (entityDescriptorData != null) { EntityDescriptor entityDescriptor = actual as EntityDescriptor; this.Assert.IsNotNull(entityDescriptor, GetVerificationFailureMessage(responseOrder, "Unexpected descriptor type:\r\nExpected: {0}\r\nActual: {1}\r\nExpected descriptor data: {2}.", typeof(EntityDescriptor).Name, actual.GetType().Name, entityDescriptorData)); this.Assert.AreSame( entityDescriptorData.Entity, entityDescriptor.Entity, GetVerificationFailureMessage(responseOrder, "Entity verification failed for the entity descriptor data: {0}.", expected)); } else if (linkDescriptorData != null) { LinkDescriptor linkDescriptor = actual as LinkDescriptor; this.Assert.IsNotNull(linkDescriptor, GetVerificationFailureMessage(responseOrder, "Unexpected descriptor type:\r\nExpected: {0}\r\nActual: {1}\r\nExpected descriptor data: {2}.", typeof(LinkDescriptor).Name, actual.GetType().Name, linkDescriptorData)); bool notMatch = linkDescriptorData.SourceDescriptor.Entity != linkDescriptor.Source || (linkDescriptorData.TargetDescriptor == null && linkDescriptor.Target != null) || (linkDescriptorData.TargetDescriptor != null && linkDescriptorData.TargetDescriptor.Entity != linkDescriptor.Target) || linkDescriptorData.SourcePropertyName != linkDescriptor.SourceProperty; this.Assert.IsFalse(notMatch, GetVerificationFailureMessage(responseOrder, "Link verification failed.\r\nExpected: {0}\r\nActual: {1}", linkDescriptorData, linkDescriptor.ToTraceString())); } else { #if WINDOWS_PHONE throw new TaupoNotSupportedException("StreamDescriptors are not supported on Windows Phone"); #else ExceptionUtilities.CheckObjectNotNull(streamDescriptorData, "Expected was not an entity, link, or stream descriptor: {0}", expected); StreamDescriptor streamDescriptor = actual as StreamDescriptor; this.Assert.IsNotNull(streamDescriptor, GetVerificationFailureMessage(responseOrder, "Unexpected descriptor type:\r\nExpected: {0}\r\nActual: {1}\r\nExpected descriptor data: {2}.", typeof(StreamDescriptor).Name, actual.GetType().Name, streamDescriptorData)); this.Assert.AreEqual(streamDescriptorData.State.ToProductEnum(), streamDescriptor.State, GetVerificationFailureMessage(responseOrder, "Stream descriptor state verification failed.")); this.Assert.AreEqual(streamDescriptorData.Name, streamDescriptor.StreamLink.Name, GetVerificationFailureMessage(responseOrder, "Stream descriptor name verification failed.")); this.Assert.AreEqual(streamDescriptorData.ETag, streamDescriptor.StreamLink.ETag, GetVerificationFailureMessage(responseOrder, "Stream descriptor etag verification failed.")); this.Assert.AreEqual(streamDescriptorData.ContentType, streamDescriptor.StreamLink.ContentType, GetVerificationFailureMessage(responseOrder, "Stream descriptor content type verification failed.")); this.Assert.AreEqual(streamDescriptorData.EditLink, streamDescriptor.StreamLink.EditLink, GetVerificationFailureMessage(responseOrder, "Stream descriptor edit link verification failed.")); this.Assert.AreEqual(streamDescriptorData.SelfLink, streamDescriptor.StreamLink.SelfLink, GetVerificationFailureMessage(responseOrder, "Stream descriptor self link verification failed.")); #endif } }
/// <summary> /// Applies all pending updates for the given entity descriptor data /// </summary> /// <param name="data">The descriptor data to update</param> public void ApplyPendingUpdates(EntityDescriptorData data) { foreach (var update in this.headerUpdates.Where(u => u.Descriptor == data).ToList()) { ExceptionUtilities.Assert(!this.ApplyUpdatesImmediately, "Should not have any pending header updates when ApplyUpdatesImmediately is true"); Apply(update); this.headerUpdates.Remove(update); } foreach (var update in this.payloadUpdates.Where(u => u.Descriptor == data).ToList()) { ExceptionUtilities.Assert(!this.ApplyUpdatesImmediately, "Should not have any pending payload updates when ApplyUpdatesImmediately is true"); Apply(update); this.payloadUpdates.Remove(update); } }
/// <summary> /// Tracks the AddRelatedObject method. /// </summary> /// <param name="data">The data service context data on which to apply state transition.</param> /// <param name="source">The source.</param> /// <param name="sourcePropertyName">Name of the source property.</param> /// <param name="target">The target.</param> public static void TrackAddRelatedObject(this DataServiceContextData data, object source, string sourcePropertyName, object target) { CheckEntityIsNotTracked(data, target); EntityDescriptorData sourceDescriptorData = GetTrackedEntityDescriptorData(data, source, "Cannot add link:", "source"); CheckStateIsNot(EntityStates.Deleted, sourceDescriptorData, "Cannot add related object:", "source"); EntityDescriptorData targetDescriptorData = data.CreateEntityDescriptorData(EntityStates.Added, data.GetNextChangeOrder(), target); data.CreateLinkDescriptorData(EntityStates.Added, uint.MaxValue, sourceDescriptorData, sourcePropertyName, targetDescriptorData); targetDescriptorData .SetParentForInsert(source) .SetParentPropertyForInsert(sourcePropertyName); }
/// <summary> /// Normalizes the given entity payload element /// </summary> /// <param name="entityPayload">The entity payload element</param> /// <param name="entityDescriptorData">The descriptor data for the entity</param> public void Normalize(EntityInstance entityPayload, EntityDescriptorData entityDescriptorData) { ExceptionUtilities.CheckArgumentNotNull(entityPayload, "entityPayload"); ExceptionUtilities.CheckArgumentNotNull(entityDescriptorData, "entityDescriptorData"); this.typeStack.Push(entityDescriptorData.EntityClrType); // do this before recursing because it could be over-written by the visit method entityPayload.FullTypeName = entityDescriptorData.ServerTypeName; entityPayload.Id = string.Empty; if (entityDescriptorData.Identity != null) { entityPayload.Id = entityDescriptorData.Identity.OriginalString; } entityPayload.Accept(this); }
private EntityInstance BuildEntityPayload( DataServiceContextData contextData, IDictionary <object, IEnumerable <NamedValue> > propertyValuesBeforeSave, EntityDescriptorData entityDescriptorData, DataServiceProtocolVersion dsv) { IEnumerable <NamedValue> propertyValues; ExceptionUtilities.Assert(propertyValuesBeforeSave.TryGetValue(entityDescriptorData.Entity, out propertyValues), "Could not find property values for descriptor: {0}", entityDescriptorData); var entityType = this.ModelSchema.EntityTypes.Single(t => t.FullName == entityDescriptorData.EntityClrType.FullName); var entityInstance = this.PayloadBuilder.EntityInstance(entityType, propertyValues); new ExpectedPayloadNormalizer(contextData, dsv).Normalize(entityInstance, entityDescriptorData); return(entityInstance); }
private HttpRequestData CreateUpdateRequest(SaveChangesOptions options, EntityDescriptorData entityDescriptorData) { HttpVerb updateVerb = HttpVerb.Patch; if (options == SaveChangesOptions.ReplaceOnUpdate) { updateVerb = HttpVerb.Put; } else if (options == SaveChangesOptions.PatchOnUpdate) { updateVerb = HttpVerb.Patch; } return(new HttpRequestData() { Verb = updateVerb, Uri = entityDescriptorData.EditLink, }); }
/// <summary> /// Tracks a pending update to the given descriptor based on values read from a response payload /// </summary> /// <param name="data">The descriptor data to update</param> /// <param name="payload">The payload that was read</param> /// <param name="baseUri">The base uri of the context</param> public void TrackUpdateFromPayload(EntityDescriptorData data, EntityInstance payload, Uri baseUri) { ExceptionUtilities.CheckArgumentNotNull(data, "data"); var update = new PayloadUpdate() { Descriptor = data, Payload = payload, BaseUri = baseUri }; if (!this.IgnoreAllUpdates) { if (this.ApplyUpdatesImmediately) { Apply(update); } else { this.payloadUpdates.Add(update); } } }
/// <summary> /// Tracks a pending update to the given descriptor based on values read from response headers /// </summary> /// <param name="data">The descriptor data to update</param> /// <param name="headers">The headers that were read</param> public void TrackUpdateFromHeaders(EntityDescriptorData data, IDictionary <string, string> headers) { ExceptionUtilities.CheckArgumentNotNull(data, "data"); var update = new HeaderUpdate() { Descriptor = data, Headers = headers }; if (!this.IgnoreAllUpdates) { if (this.ApplyUpdatesImmediately) { Apply(update); } else { this.headerUpdates.Add(update); } } }
/// <summary> /// Tracks the SetLink method. /// </summary> /// <param name="data">The data service context data on which to apply state transition.</param> /// <param name="source">The source.</param> /// <param name="sourcePropertyName">Name of the source property.</param> /// <param name="target">The target.</param> public static void TrackSetLink(this DataServiceContextData data, object source, string sourcePropertyName, object target) { ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(sourcePropertyName, "sourcePropertyName"); EntityDescriptorData sourceDescriptorData = GetTrackedEntityDescriptorData(data, source, "Cannot set link:", "source"); CheckStateIsNot(EntityStates.Deleted, sourceDescriptorData, "Cannot set link:", "source"); EntityDescriptorData targetDescriptorData = null; if (target != null) { targetDescriptorData = GetTrackedEntityDescriptorData(data, target, "Cannot set link:", "target"); CheckStateIsNot(EntityStates.Deleted, sourceDescriptorData, "Cannot set link:", "target"); } var relatedToSource = data.LinkDescriptorsData.Where(e => e.SourceDescriptor.Entity == source && e.SourcePropertyName == sourcePropertyName).ToList(); if (relatedToSource.Count > 1) { throw new TaupoInvalidOperationException("Cannot set link: source contains multiple links for the property: " + sourcePropertyName); } LinkDescriptorData existingLinkDescriptorData = relatedToSource.FirstOrDefault(); if (existingLinkDescriptorData == null) { data.CreateLinkDescriptorData(EntityStates.Modified, data.GetNextChangeOrder(), sourceDescriptorData, sourcePropertyName, targetDescriptorData); } else { if (existingLinkDescriptorData.State != EntityStates.Modified || existingLinkDescriptorData.TargetDescriptor != targetDescriptorData) { data.ChangeStateAndChangeOrder(existingLinkDescriptorData, EntityStates.Modified, data.GetNextChangeOrder()); } existingLinkDescriptorData.TargetDescriptor = targetDescriptorData; } }
private EntityDescriptor GetEntityDescriptor(EntityDescriptorData entityDescriptorData) { EntityDescriptor descriptor = null; if (entityDescriptorData.Entity != null) { descriptor = this.context.GetEntityDescriptor(entityDescriptorData.Entity); } else { ExceptionUtilities.Assert(entityDescriptorData.Identity == null, "Entity descriptor's Identity cannnot be null when entity is null."); descriptor = this.FindEntityDescriptorWithIdentity(entityDescriptorData.Identity); } if (descriptor == null) { throw new AssertionFailedException( string.Format(CultureInfo.InvariantCulture, "Entity descriptor is missing from the data service context. Expected entity descriptor: {{{0}}}.", entityDescriptorData)); } return(descriptor); }
private ExpectedClientRequest CreateEntityDeleteRequest(EntityDescriptorData entityDescriptorData, SaveChangesOptions options) { var request = new ExpectedClientRequest() { Verb = HttpVerb.Delete, Uri = entityDescriptorData.EditLink, }; request.Headers[HttpHeaders.IfMatch] = entityDescriptorData.ETag; request.Headers[HttpHeaders.Prefer] = null; request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(DataServiceProtocolVersion.V4); this.SetDefaultAcceptHeader(request, options); request.Headers[HttpHeaders.ContentType] = null; string hintString = @"Entity delete\r\n{{\r\n Descriptor = {0}\r\n}}"; request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, entityDescriptorData); return(request); }
private void AddFoldedLinksToEntityInsertPayload(DataServiceContextData contextData, EntityDescriptorData entityDescriptorData, EntityInstance payload) { var entityType = this.ModelSchema.EntityTypes.Single(t => t.FullName == entityDescriptorData.EntityClrType.FullName); foreach (var linkDescriptor in contextData.LinkDescriptorsData.Where(l => l.SourceDescriptor == entityDescriptorData)) { if (linkDescriptor.TargetDescriptor.State == EntityStates.Added) { continue; } var navigationProperty = entityType.AllNavigationProperties.Single(n => n.Name == linkDescriptor.SourcePropertyName); string contentType = MimeTypes.ApplicationAtomXml + ";type="; if (navigationProperty.ToAssociationEnd.Multiplicity == EndMultiplicity.Many) { contentType += "feed"; } else { contentType += "entry"; } // note: the edit-link is used rather than identity because the server needs to be able to query for the target entity // and the identity may not be an actual uri var link = new DeferredLink() { UriString = linkDescriptor.TargetDescriptor.EditLink.OriginalString } .WithContentType(contentType).WithTitleAttribute(linkDescriptor.SourcePropertyName); payload.Add(new NavigationPropertyInstance(linkDescriptor.SourcePropertyName, link)); } }
private ExpectedClientRequest CreateEntityInsertRequest(DataServiceContextData contextData, IDictionary <object, IEnumerable <NamedValue> > propertyValuesBeforeSave, EntityDescriptorData entityDescriptorData, SaveChangesOptions options) { ExceptionUtilities.Assert(!entityDescriptorData.IsMediaLinkEntry, "Can only be used for non media-link-entries"); var insertUri = GetEntityInsertUri(contextData, entityDescriptorData); ExpectedClientRequest request = new ExpectedClientRequest() { Verb = HttpVerb.Post, Uri = insertUri }; string preference = contextData.AddAndUpdateResponsePreference.ToHeaderValue(); DataServiceProtocolVersion dsv = GetDataServiceVersion(HttpVerb.Post, preference); dsv = dsv.IncreaseVersionIfRequired(this.VersionCalculator.CalculateDataServiceVersion(entityDescriptorData, contextData.MaxProtocolVersion)); var payload = this.BuildEntityPayload(contextData, propertyValuesBeforeSave, entityDescriptorData, dsv); request.Body = payload; this.AddFoldedLinksToEntityInsertPayload(contextData, entityDescriptorData, payload); request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(dsv); request.Headers[HttpHeaders.IfMatch] = null; request.Headers[HttpHeaders.Prefer] = preference; this.SetDefaultAcceptHeader(request, options); this.SetContentTypeHeaderForEntity(request); string hintString = @"Entity insert\r\n{{\r\n Descriptor = {0}\r\n Options = {1}\r\n}}"; request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, entityDescriptorData, options); return(request); }
private void VerifyEntityDescriptor(EntityDescriptorData expectedDescriptorData, EntityDescriptor actualDescriptor) { VerifyState(expectedDescriptorData, actualDescriptor); VerifyETag(expectedDescriptorData.ETag, actualDescriptor.ETag, expectedDescriptorData); VerifyExpectedVsActual(expectedDescriptorData.ServerTypeName, actualDescriptor.ServerTypeName, expectedDescriptorData, "ServerTypeName"); VerifyExpectedVsActual(expectedDescriptorData.Identity, actualDescriptor.Identity, expectedDescriptorData, "Identity"); VerifyExpectedVsActual(expectedDescriptorData.EditLink, actualDescriptor.EditLink, expectedDescriptorData, "EditLink"); EntityDescriptor expectedParentForInsert = null; if (expectedDescriptorData.ParentForInsert != null) { EntityDescriptorData parentForInsertDescriptorData; if (!this.contextData.TryGetEntityDescriptorData(expectedDescriptorData.ParentForInsert, out parentForInsertDescriptorData)) { throw new TaupoInvalidOperationException( string.Format( CultureInfo.InvariantCulture, "Expected context data should have entity descriptor for the parent for insert {0}. Descriptor data = {1}.", expectedDescriptorData.ParentForInsert, expectedDescriptorData)); } expectedParentForInsert = this.GetEntityDescriptor(parentForInsertDescriptorData); } VerifyExpectedVsActual(expectedParentForInsert, actualDescriptor.ParentForInsert, expectedDescriptorData, "ParentForInsert"); VerifyExpectedVsActual(expectedDescriptorData.ParentPropertyForInsert, actualDescriptor.ParentPropertyForInsert, expectedDescriptorData, "ParentPropertyForInsert"); if (actualDescriptor.ParentForInsert == null) { ExceptionUtilities.Assert(actualDescriptor.ParentPropertyForInsert == null, "ParentPropertyForInsert must be null when ParentForInsert is null."); } else { ExceptionUtilities.Assert(!string.IsNullOrEmpty(actualDescriptor.ParentPropertyForInsert), "ParentPropertyForInsert cannot be null or empty when ParentForInsert is not null."); } VerifyExpectedVsActual(expectedDescriptorData.EditLink, actualDescriptor.EditLink, expectedDescriptorData, "EditLink"); VerifyExpectedVsActual(expectedDescriptorData.SelfLink, actualDescriptor.SelfLink, expectedDescriptorData, "SelfLink"); VerifyExpectedVsActual(expectedDescriptorData.EditStreamUri, actualDescriptor.EditStreamUri, expectedDescriptorData, "EditStreamUri"); VerifyExpectedVsActual(expectedDescriptorData.ReadStreamUri, actualDescriptor.ReadStreamUri, expectedDescriptorData, "ReadStreamUri"); VerifyExpectedVsActual(expectedDescriptorData.StreamETag, actualDescriptor.StreamETag, expectedDescriptorData, "StreamETag"); // Check that the internal StreamDescriptor for the default stream is in the correct state, if we can do the reflection safely. // Note that if the descriptor is not an MLE, we don't check whether the internal value is null, since that is very much an implementation detail #if !SILVERLIGHT if (expectedDescriptorData.IsMediaLinkEntry && AppDomain.CurrentDomain.IsFullyTrusted) { var defaultStreamDescriptorProperty = typeof(EntityDescriptor).GetProperty("DefaultStreamDescriptor", BindingFlags.Instance | BindingFlags.NonPublic); ExceptionUtilities.CheckObjectNotNull(defaultStreamDescriptorProperty, "Could not find property 'DefaultStreamDescriptor' on EntityDescriptor"); var defaultStreamDescriptor = (StreamDescriptor)defaultStreamDescriptorProperty.GetValue(actualDescriptor, null); ExceptionUtilities.CheckObjectNotNull(defaultStreamDescriptor, "Product's default stream descriptor was null for entity descriptor: {0}", expectedDescriptorData); var defaultStreamState = defaultStreamDescriptor.State; VerifyExpectedVsActual(expectedDescriptorData.DefaultStreamState, defaultStreamState.ToTestEnum(), expectedDescriptorData, "DefaultStreamDesciptor.State"); } #endif #if !WINDOWS_PHONE VerifyExpectedVsActual(expectedDescriptorData.LinkInfos.Count, actualDescriptor.LinkInfos.Count, expectedDescriptorData, "LinkInfos.Count"); for (int i = 0; i < expectedDescriptorData.LinkInfos.Count; i++) { var expectedLinkInfo = expectedDescriptorData.LinkInfos.ElementAt(i); var actualLinkInfo = actualDescriptor.LinkInfos.ElementAt(i); VerifyExpectedVsActual(expectedLinkInfo.Name, actualLinkInfo.Name, expectedDescriptorData, "LinkInfos[" + i + "].Name"); VerifyExpectedVsActual(expectedLinkInfo.NavigationLink, actualLinkInfo.NavigationLink, expectedDescriptorData, "LinkInfos[" + i + "].NavigationLink"); VerifyExpectedVsActual(expectedLinkInfo.RelationshipLink, actualLinkInfo.AssociationLink, expectedDescriptorData, "LinkInfos[" + i + "].AssociationLink"); } VerifyExpectedVsActual(expectedDescriptorData.OperationDescriptors.Count, actualDescriptor.OperationDescriptors.Count, expectedDescriptorData, "OperationDescriptors.Count"); for (int i = 0; i < expectedDescriptorData.OperationDescriptors.Count; i++) { var expectedOperationDescriptor = expectedDescriptorData.OperationDescriptors.ElementAt(i); var actualOperationDescriptor = actualDescriptor.OperationDescriptors.ElementAt(i); VerifyExpectedVsActual(expectedOperationDescriptor.Metadata, actualOperationDescriptor.Metadata, expectedDescriptorData, "OperationDescriptors[" + i + "].Metadata"); VerifyExpectedVsActual(expectedOperationDescriptor.Target, actualOperationDescriptor.Target, expectedDescriptorData, "OperationDescriptors[" + i + "].Target"); VerifyExpectedVsActual(expectedOperationDescriptor.Title, actualOperationDescriptor.Title, expectedDescriptorData, "OperationDescriptors[" + i + "].Title"); VerifyExpectedVsActual(expectedOperationDescriptor.IsAction, actualOperationDescriptor is ActionDescriptor, "OperationDescriptors[" + i + "].IsAction"); } VerifyExpectedVsActual(expectedDescriptorData.StreamDescriptors.Count, actualDescriptor.StreamDescriptors.Count, expectedDescriptorData, "StreamDescriptors.Count"); for (int i = 0; i < expectedDescriptorData.StreamDescriptors.Count; i++) { var expectedStreamDescriptor = expectedDescriptorData.StreamDescriptors.ElementAt(i); var actualStreamDescriptor = actualDescriptor.StreamDescriptors.ElementAt(i); VerifyExpectedVsActual(expectedStreamDescriptor.Name, actualStreamDescriptor.StreamLink.Name, expectedDescriptorData, "StreamDescriptors[" + i + "].Name"); VerifyExpectedVsActual(expectedStreamDescriptor.ContentType, actualStreamDescriptor.StreamLink.ContentType, expectedDescriptorData, "StreamDescriptors[" + i + "].ContentType"); VerifyExpectedVsActual(expectedStreamDescriptor.EditLink, actualStreamDescriptor.StreamLink.EditLink, expectedDescriptorData, "StreamDescriptors[" + i + "].EditLink"); VerifyExpectedVsActual(expectedStreamDescriptor.ETag, actualStreamDescriptor.StreamLink.ETag, expectedDescriptorData, "StreamDescriptors[" + i + "].ETag"); VerifyExpectedVsActual(expectedStreamDescriptor.SelfLink, actualStreamDescriptor.StreamLink.SelfLink, expectedDescriptorData, "StreamDescriptors[" + i + "].SelfLink"); ExceptionUtilities.Assert(object.ReferenceEquals(expectedDescriptorData, expectedStreamDescriptor.EntityDescriptor), "Stream descriptor data had unexpected entity descriptor data"); VerifyExpectedVsActual(actualDescriptor, actualStreamDescriptor.EntityDescriptor, expectedDescriptorData, "StreamDescriptors[" + i + "].EntityDescriptor"); } #endif }
private static void VerifyETag(string expectedETag, string actualETag, EntityDescriptorData entityEntry) { VerifyExpectedVsActual(expectedETag, actualETag, entityEntry, "ETag"); }
private ExpectedClientRequest CreateEntityUpdateRequest(DataServiceContextData contextData, IDictionary <object, IEnumerable <NamedValue> > propertyValuesBeforeSave, EntityDescriptorData entityDescriptorData, SaveChangesOptions options) { var request = new ExpectedClientRequest() { Verb = GetUpdateVerb(options), Uri = entityDescriptorData.EditLink, }; string preference = contextData.AddAndUpdateResponsePreference.ToHeaderValue(); var dsv = GetDataServiceVersion(request.Verb, preference); dsv = dsv.IncreaseVersionIfRequired(this.VersionCalculator.CalculateDataServiceVersion(entityDescriptorData, contextData.MaxProtocolVersion)); request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(dsv); request.Headers[HttpHeaders.IfMatch] = entityDescriptorData.ETag; request.Headers[HttpHeaders.Prefer] = preference; this.SetDefaultAcceptHeader(request, options); this.SetContentTypeHeaderForEntity(request); request.Body = this.BuildEntityPayload(contextData, propertyValuesBeforeSave, entityDescriptorData, dsv); string hintString = @"Entity update\r\n{{\r\n Descriptor = {0}\r\n Options = {1}\r\n}}"; request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, entityDescriptorData, options); return(request); }
private void ApplyNextResponseHeadersAndPayload(DataServiceContextData dataBeforeSaveChanges, EntityDescriptorData entityDescriptorData, Queue <DSClient.OperationResponse> responseQueue) { ExceptionUtilities.CheckArgumentNotNull(dataBeforeSaveChanges, "dataBeforeSaveChanges"); ExceptionUtilities.CheckArgumentNotNull(entityDescriptorData, "entityDescriptorData"); ExceptionUtilities.CheckArgumentNotNull(responseQueue, "responseQueue"); ExceptionUtilities.Assert(responseQueue.Count > 0, "Response queue unexpectedly empty"); var responseForRequest = responseQueue.Dequeue(); entityDescriptorData.UpdateFromHeaders(responseForRequest.Headers); }
private HttpRequestData CreateInsertRequest(DataServiceContextData dataBeforeSaveChanges, EntityDescriptorData entityDescriptorData) { Uri insertUri; if (entityDescriptorData.InsertLink != null) { insertUri = entityDescriptorData.InsertLink; } else { ExceptionUtilities.CheckObjectNotNull(entityDescriptorData.ParentForInsert, "Entity descriptor data did not have insert link or parent for insert: {0}", entityDescriptorData); ExceptionUtilities.CheckObjectNotNull(entityDescriptorData.ParentPropertyForInsert, "Entity descriptor data did not have insert link or parent property for insert: {0}", entityDescriptorData); var parentDescriptor = dataBeforeSaveChanges.GetEntityDescriptorData(entityDescriptorData.ParentForInsert); var linkInfo = parentDescriptor.LinkInfos.SingleOrDefault(l => l.Name == entityDescriptorData.ParentPropertyForInsert); if (linkInfo != null && linkInfo.NavigationLink != null) { insertUri = linkInfo.NavigationLink; } else { insertUri = new Uri(UriHelpers.ConcatenateUriSegments(parentDescriptor.EditLink.OriginalString, entityDescriptorData.ParentPropertyForInsert)); } } return(new HttpRequestData() { Verb = HttpVerb.Post, Uri = insertUri }); }
/// <summary> /// Initializes a new instance of the <see cref="EntityChangeData"/> class. /// </summary> /// <param name="entityDescriptorData">The entity descriptor data.</param> protected EntityChangeData(EntityDescriptorData entityDescriptorData) : base(entityDescriptorData) { this.CachedPropertiesValues = new Dictionary <string, object>(); }