private void WriteEntry(IExpandedResult expanded, object element, bool resourceInstanceInFeed, ResourceType expectedType) { Uri uri; Func <ProjectionNode, bool> predicate = null; base.IncrementSegmentResultCount(); ODataEntry entry = new ODataEntry(); AtomEntryMetadata annotation = new AtomEntryMetadata(); entry.SetAnnotation <AtomEntryMetadata>(annotation); string name = expectedType.Name; ResourceType actualResourceType = WebUtil.GetNonPrimitiveResourceType(base.Provider, element); if (actualResourceType.ResourceTypeKind != ResourceTypeKind.EntityType) { throw new DataServiceException(500, System.Data.Services.Strings.BadProvider_InconsistentEntityOrComplexTypeUsage(actualResourceType.FullName)); } Uri absoluteUri = Serializer.GetIdAndEditLink(element, actualResourceType, base.Provider, base.CurrentContainer, base.AbsoluteServiceUri, out uri); Uri relativeUri = new Uri(absoluteUri.AbsoluteUri.Substring(base.AbsoluteServiceUri.AbsoluteUri.Length), UriKind.Relative); entry.MediaResource = this.GetMediaResource(element, actualResourceType, name, relativeUri); entry.TypeName = actualResourceType.FullName; entry.Id = uri.AbsoluteUri; entry.EditLink = relativeUri; AtomLinkMetadata metadata2 = new AtomLinkMetadata { Title = name }; annotation.EditLink = metadata2; string eTagValue = base.GetETagValue(element, actualResourceType); if (eTagValue != null) { entry.ETag = eTagValue; } IEnumerable <ProjectionNode> projections = base.GetProjections(); if (projections != null) { if (predicate == null) { predicate = projectionNode => projectionNode.TargetResourceType.IsAssignableFrom(actualResourceType); } projections = projections.Where <ProjectionNode>(predicate); entry.SetAnnotation <ProjectedPropertiesAnnotation>(new ProjectedPropertiesAnnotation(from p in projections select p.PropertyName)); } entry.AssociationLinks = this.GetEntityAssociationLinks(actualResourceType, relativeUri, projections); this.PopulateODataOperations(element, resourceInstanceInFeed, entry, actualResourceType); this.odataWriter.WriteStart(entry); this.WriteNavigationProperties(expanded, element, resourceInstanceInFeed, actualResourceType, absoluteUri, relativeUri, projections); entry.Properties = this.GetEntityProperties(element, actualResourceType, relativeUri, projections); this.odataWriter.WriteEnd(); }
/// <summary> /// Creates and returns an ODataEntry from the given value. /// </summary> /// <param name="entityType">The value type.</param> /// <param name="value">The entry value.</param> /// <param name="properties">The given properties to serialize.</param> /// <returns>An ODataEntry representing the given value.</returns> internal ODataEntry CreateODataEntry(Type entityType, object value, params ClientPropertyAnnotation[] properties) { Debug.Assert(entityType != null, "entityType != null"); Debug.Assert(value != null, "value != null"); ClientEdmModel model = this.requestInfo.Model; ClientTypeAnnotation entityTypeAnnotation = model.GetClientTypeAnnotation(entityType); Debug.Assert(entityTypeAnnotation != null, "entityTypeAnnotation != null"); Debug.Assert(entityTypeAnnotation.IsEntityType, "Unexpected type"); ODataEntry odataEntityValue = new ODataEntry() { TypeName = entityTypeAnnotation.ElementTypeName, }; string serverTypeName = this.requestInfo.GetServerTypeName(entityTypeAnnotation); odataEntityValue.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = serverTypeName }); odataEntityValue.Properties = this.PopulateProperties(value, serverTypeName, properties.Any() ? properties : entityTypeAnnotation.PropertiesToSerialize(), null); return(odataEntityValue); }
private void EndEntry() { IODataAtomReaderEntryState currentEntryState = this.CurrentEntryState; ODataEntry entry = currentEntryState.Entry; if (entry != null) { if (currentEntryState.CachedEpm != null) { AtomScope currentScope = (AtomScope)base.CurrentScope; if (currentScope.HasAtomEntryMetadata) { EpmSyndicationReader.ReadEntryEpm(currentEntryState, this.atomInputContext); } if (currentScope.HasEpmCustomReaderValueCache) { EpmCustomReader.ReadEntryEpm(currentEntryState, this.atomInputContext); } } if (currentEntryState.AtomEntryMetadata != null) { entry.SetAnnotation <AtomEntryMetadata>(currentEntryState.AtomEntryMetadata); } IEdmEntityType entityType = currentEntryState.EntityType; if ((!currentEntryState.MediaLinkEntry.HasValue && (entityType != null)) && this.atomInputContext.Model.HasDefaultStream(entityType)) { ODataAtomEntryAndFeedDeserializer.EnsureMediaResource(currentEntryState, true); } bool validateMediaResource = this.atomInputContext.UseDefaultFormatBehavior || this.atomInputContext.UseServerFormatBehavior; ValidationUtils.ValidateEntryMetadata(entry, entityType, this.atomInputContext.Model, validateMediaResource); } this.ReplaceScope(ODataReaderState.EntryEnd); }
private void TryAnnotateV2FeedPackage(ODataEntry entry, EntityInstanceContext entityInstanceContext) { var instance = entityInstanceContext.EntityInstance as ODataPackage; if (instance != null) { // Set Atom entry metadata var atomEntryMetadata = new AtomEntryMetadata(); atomEntryMetadata.Title = instance.Id; if (!string.IsNullOrEmpty(instance.Authors)) { atomEntryMetadata.Authors = new[] { new AtomPersonMetadata { Name = instance.Authors } } } ; if (instance.Published > DateTime.MinValue) { atomEntryMetadata.Published = instance.Published; } if (!string.IsNullOrEmpty(instance.Summary)) { atomEntryMetadata.Summary = instance.Summary; } entry.SetAnnotation(atomEntryMetadata); // Set the ID and links. We have to do this because the self link should have a version containing // SemVer 2.0.0 metadata (e.g. 1.0.0+git). entry.Id = BuildId(instance, entityInstanceContext); entry.ReadLink = new Uri(entry.Id); entry.EditLink = new Uri(entry.Id); // Add package download link entry.MediaResource = new ODataStreamReferenceValue { ContentType = ContentType, ReadLink = BuildLinkForStreamProperty(instance, entityInstanceContext) }; // Make the download action target match the media resource link. entry.Actions = entry .Actions .Select(action => { if (StringComparer.OrdinalIgnoreCase.Equals("Download", action.Title)) { return new ODataAction { Metadata = action.Metadata, Target = entry.MediaResource.ReadLink, Title = action.Title } } ; return(action); }) .ToList(); } }
public void ReadEditLinkShouldBeOmittedWhenNeitherSetInAtom() { DateTimeOffset updatedTime = DateTimeOffset.UtcNow; var entry = new ODataEntry { Id = new Uri("http://test.org/EntitySet('1')") }; entry.SetAnnotation(new AtomEntryMetadata() { Updated = updatedTime }); string actual = this.WriteAtomEntry(entry); string expected = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://temp.org/$metadata#EntitySet/$entity\">" + "<id>http://test.org/EntitySet('1')</id>" + "<title />" + "<updated>" + ODataAtomConvert.ToAtomString(updatedTime) + "</updated>" + "<author>" + "<name />" + "</author>" + "<content type=\"application/xml\" />" + "</entry>"; Assert.Equal(expected, actual); }
/// <summary> /// Creates a new ODataEntry from the specified entity set, instance, and type. /// </summary> /// <param name="entitySet">Entity set for the new entry.</param> /// <param name="value">Entity instance for the new entry.</param> /// <param name="entityType">Entity type for the new entry.</param> /// <returns>New ODataEntry with the specified entity set and type, property values from the specified instance.</returns> internal static ODataEntry CreateODataEntry(IEdmEntitySet entitySet, IEdmStructuredValue value, IEdmEntityType entityType) { var entry = new ODataEntry(); entry.SetAnnotation(new ODataTypeAnnotation(entitySet, entityType)); entry.Properties = value.PropertyValues.Select(p => { object propertyValue; if (p.Value.ValueKind == EdmValueKind.Null) { propertyValue = null; } else if (p.Value is IEdmPrimitiveValue) { propertyValue = ((IEdmPrimitiveValue)p.Value).ToClrValue(); } else { Assert.True(false, "Test only currently supports creating ODataEntry from IEdmPrimitiveValue instances."); return(null); } return(new ODataProperty() { Name = p.Name, Value = propertyValue }); }); return(entry); }
/// <summary> /// Creates an ODataEntry for the given EntityDescriptor and fills in its ODataLib metadata. /// </summary> /// <param name="entityDescriptor">The entity descriptor.</param> /// <param name="serverTypeName">Name of the server type.</param> /// <param name="entityType">The client-side entity type.</param> /// <param name="clientFormat">The current client format.</param> /// <returns>An odata entry with its metadata filled in.</returns> internal static ODataEntry CreateODataEntry(EntityDescriptor entityDescriptor, string serverTypeName, ClientTypeAnnotation entityType, DataServiceClientFormat clientFormat) { ODataEntry entry = new ODataEntry(); // If the client type name is different from the server type name, then add SerializationTypeNameAnnotation // which tells ODataLib to write the type name in the annotation in the payload. if (entityType.ElementTypeName != serverTypeName) { entry.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = serverTypeName }); } // We always need to write the client type name, since this is the type name used by ODataLib // to resolve the entity type using EdmModel.FindSchemaElement. entry.TypeName = entityType.ElementTypeName; // Continue to send the entry's ID in update payloads in Atom for compatibility with V1-V3, // but for JSON-Light we do not want the extra information on the wire. if (clientFormat.UsingAtom && EntityStates.Modified == entityDescriptor.State) { // <id>http://host/service/entityset(key)</id> entry.Id = entityDescriptor.GetLatestIdentity(); } if (entityDescriptor.IsMediaLinkEntry || entityType.IsMediaLinkEntry) { // Since we are already enabled EnableWcfDataServicesClientBehavior in the writer settings, // setting the MediaResource value will tell ODataLib to write MLE payload, irrespective of // what the metadata says. entry.MediaResource = new ODataStreamReferenceValue(); } return(entry); }
public void ReadLinkShouldNotBeOmittedWhenNotIdenticalToEditLink() { DateTimeOffset updatedTime = DateTimeOffset.UtcNow; var entry = new ODataEntry { Id = new Uri("http://test.org/EntitySet('1')"), EditLink = new Uri("http://test.org/EntitySet('1')/edit"), ReadLink = new Uri("http://test.org/EntitySet('1')/read") }; entry.SetAnnotation(new AtomEntryMetadata() { Updated = updatedTime }); string actual = this.WriteAtomEntry(entry); string expected = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://temp.org/$metadata#EntitySet/$entity\">" + "<id>http://test.org/EntitySet('1')</id>" + "<link rel=\"edit\" href=\"http://test.org/EntitySet('1')/edit\" />" + "<link rel=\"self\" href=\"http://test.org/EntitySet('1')/read\" />" + "<title />" + "<updated>" + ODataAtomConvert.ToAtomString(updatedTime) + "</updated>" + "<author>" + "<name />" + "</author>" + "<content type=\"application/xml\" />" + "</entry>"; Assert.Equal(expected, actual); }
private static ODataEntry CreateEntryWithKeyAsSegmentConvention(bool addAnnotation, bool? useKeyAsSegment) { var model = new EdmModel(); var container = new EdmEntityContainer("Fake", "Container"); model.AddElement(container); if (addAnnotation) { model.AddVocabularyAnnotation(new EdmAnnotation(container, UrlConventionsConstants.ConventionTerm, UrlConventionsConstants.KeyAsSegmentAnnotationValue)); } EdmEntityType entityType = new EdmEntityType("Fake", "FakeType"); entityType.AddKeys(entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); model.AddElement(entityType); var entitySet = new EdmEntitySet(container, "FakeSet", entityType); container.AddElement(entitySet); var metadataContext = new ODataMetadataContext( true, ODataReaderBehavior.DefaultBehavior.OperationsBoundToEntityTypeMustBeContainerQualified, new EdmTypeReaderResolver(model, ODataReaderBehavior.DefaultBehavior), model, new Uri("http://temp.org/$metadata"), null /*requestUri*/); var thing = new ODataEntry {Properties = new[] {new ODataProperty {Name = "Id", Value = 1}}}; thing.SetAnnotation(new ODataTypeAnnotation(entitySet, entityType)); thing.MetadataBuilder = metadataContext.GetEntityMetadataBuilderForReader(new TestJsonLightReaderEntryState { Entry = thing, SelectedProperties = new SelectedPropertiesNode("*")}, useKeyAsSegment); return thing; }
internal static void AddTypeNameAnnotationAsNeeded(ODataEntry entry, IEdmEntityType odataPathType, ODataMetadataLevel metadataLevel) { // ODataLib normally has the caller decide whether or not to serialize properties by leaving properties // null when values should not be serialized. The TypeName property is different and should always be // provided to ODataLib to enable model validation. A separate annotation is used to decide whether or not // to serialize the type name (a null value prevents serialization). // Note that this annotation should not be used for Atom or JSON verbose formats, as it will interfere with // the correct default behavior for those formats. Contract.Assert(entry != null); // Only add an annotation if we want to override ODataLib's default type name serialization behavior. if (ShouldAddTypeNameAnnotation(metadataLevel)) { string typeName; // Provide the type name to serialize (or null to force it not to serialize). if (ShouldSuppressTypeNameSerialization(entry, odataPathType, metadataLevel)) { typeName = null; } else { typeName = entry.TypeName; } entry.SetAnnotation <SerializationTypeNameAnnotation>(new SerializationTypeNameAnnotation { TypeName = typeName }); } }
internal static void AddTypeNameAnnotationAsNeeded(ODataEntry entry, IEdmEntityType odataPathType, ODataMetadataLevel metadataLevel) { // ODataLib normally has the caller decide whether or not to serialize properties by leaving properties // null when values should not be serialized. The TypeName property is different and should always be // provided to ODataLib to enable model validation. A separate annotation is used to decide whether or not // to serialize the type name (a null value prevents serialization). // Note: In the current version of ODataLib the default behavior likely now matches the requirements for // minimal metadata mode. However, there have been behavior changes/bugs there in the past, so the safer // option is for this class to take control of type name serialization in minimal metadata mode. Contract.Assert(entry != null); string typeName = null; // Set null to force the type name not to serialize. // Provide the type name to serialize. if (!ShouldSuppressTypeNameSerialization(entry, odataPathType, metadataLevel)) { typeName = entry.TypeName; } entry.SetAnnotation <SerializationTypeNameAnnotation>(new SerializationTypeNameAnnotation { TypeName = typeName }); }
private void TryAnnotateV2FeedPackage(ODataEntry entry, EntityInstanceContext entityInstanceContext) { var instance = entityInstanceContext.EntityInstance as V2FeedPackage; if (instance != null) { // Set Atom entry metadata var atomEntryMetadata = new AtomEntryMetadata(); atomEntryMetadata.Title = instance.Id; if (!string.IsNullOrEmpty(instance.Authors)) { atomEntryMetadata.Authors = new[] { new AtomPersonMetadata { Name = instance.Authors } }; } if (instance.LastUpdated > DateTime.MinValue) { atomEntryMetadata.Updated = instance.LastUpdated; } if (!string.IsNullOrEmpty(instance.Summary)) { atomEntryMetadata.Summary = instance.Summary; } entry.SetAnnotation(atomEntryMetadata); // Add package download link entry.MediaResource = new ODataStreamReferenceValue { ContentType = ContentType, ReadLink = BuildLinkForStreamProperty("v2", instance.Id, instance.Version, entityInstanceContext.Request) }; } }
public void FlagsEnumAsEntityProperty_NullAsValue_ButNonNullable_GetNullError() { DateTimeOffset updatedTime = DateTimeOffset.UtcNow; Func <ODataEntry> entryClone = () => { var tmp = new ODataEntry { TypeName = "NS.MyEntityType", Properties = new[] { new ODataProperty { Name = "ColorFlags", Value = null } }, SerializationInfo = MySerializationInfo }; tmp.SetAnnotation(new AtomEntryMetadata() { Updated = updatedTime }); return(tmp); }; string fullName = this.entityType.FindProperty("ColorFlags").Type.FullName(); // model-request Action action = () => this.WriteRequestWithModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: ""); action.ShouldThrow <ODataException>().WithMessage(Strings.WriterValidationUtils_NonNullablePropertiesMustNotHaveNullValue("ColorFlags", fullName)); // model-reseponse action = () => this.WriteResponseWithModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: ""); action.ShouldThrow <ODataException>().WithMessage(Strings.WriterValidationUtils_NonNullablePropertiesMustNotHaveNullValue("ColorFlags", fullName)); // NoModel-request string expectedPayload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" " + "xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://odata.org/test/$metadata#MySet/$entity\">" + "<category term=\"#NS.MyEntityType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />" + "<id />" + "<title />" + "<updated>" + ODataAtomConvert.ToAtomString(updatedTime) + "</updated>" + "<author><name /></author>" + "<content type=\"application/xml\">" + "<m:properties>" + "<d:ColorFlags m:null=\"true\" />" + "</m:properties>" + "</content>" + "</entry>"; this.WriteRequestWithoutModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // NoModel-response this.WriteResponseWithoutModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); }
public JsonMinimalMetadataTypeNameOracleTests() { entryWithTypeAnnotationAndTypeName.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = "TypeNameFromSTNA" }); entryWithTypeAnnotationWithoutTypeName.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = "TypeNameFromSTNA" }); }
/// <summary> /// Creates the materializer entry. /// </summary> /// <param name="entry">The entry.</param> /// <param name="format">The format the entry was read in.</param> /// <param name="isTracking">True if the contents of the entry will be tracked in the context, otherwise False.</param> /// <param name="model">The client model.</param> /// <returns>A new materializer entry.</returns> public static MaterializerEntry CreateEntry(ODataEntry entry, ODataFormat format, bool isTracking, ClientEdmModel model) { Debug.Assert(entry.GetAnnotation <MaterializerEntry>() == null, "MaterializerEntry has already been created."); MaterializerEntry materializerEntry = new MaterializerEntry(entry, format, isTracking, model); entry.SetAnnotation <MaterializerEntry>(materializerEntry); return(materializerEntry); }
private static XmlReader EntryXmlCustomizer(ODataEntry entry, XmlReader entryReader, Uri baseUri) { XElement payload = XElement.Load(entryReader.ReadSubtree(), LoadOptions.None); entryReader.Read(); entry.SetAnnotation <ReadingEntityInfo>(new ReadingEntityInfo(payload, baseUri)); XmlReader reader = payload.CreateReader(); reader.Read(); return(reader); }
public void FlagsEnumAsEntityProperty_StrAsValue_StrAsTypeName() { DateTimeOffset updatedTime = DateTimeOffset.UtcNow; Func <ODataEntry> entryClone = () => { var tmp = new ODataEntry { TypeName = "NS.MyEntityType", Properties = new[] { new ODataProperty { Name = "ColorFlags", Value = new ODataEnumValue( (ColorFlags.Green | ColorFlags.Red).ToString(CultureInfo.InvariantCulture), "NS.MyEnumTypeName") // type name } }, SerializationInfo = MySerializationInfo }; tmp.SetAnnotation(new AtomEntryMetadata() { Updated = updatedTime }); return(tmp); }; // model-request string expectedPayload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" " + "xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://odata.org/test/$metadata#MySet/$entity\">" + "<category term=\"#NS.MyEntityType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />" + "<id />" + "<title />" + "<updated>" + ODataAtomConvert.ToAtomString(updatedTime) + "</updated>" + "<author><name /></author>" + "<content type=\"application/xml\">" + "<m:properties>" + "<d:ColorFlags m:type=\"#NS.MyEnumTypeName\">Red, Green</d:ColorFlags>" + "</m:properties>" + "</content>" + "</entry>"; this.WriteRequestWithModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // model-reseponse this.WriteResponseWithModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // NoModel-request this.WriteRequestWithoutModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // NoModel-response this.WriteResponseWithoutModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); }
public static AtomEntryMetadata Atom(this ODataEntry entry) { ExceptionUtils.CheckArgumentNotNull <ODataEntry>(entry, "entry"); AtomEntryMetadata annotation = entry.GetAnnotation <AtomEntryMetadata>(); if (annotation == null) { annotation = new AtomEntryMetadata(); entry.SetAnnotation <AtomEntryMetadata>(annotation); } return(annotation); }
internal void WriteEntry(EntityDescriptor entityDescriptor, IEnumerable <LinkDescriptor> relatedLinks, ODataRequestMessageWrapper requestMessage) { ClientEdmModel model = ClientEdmModel.GetModel(this.requestInfo.MaxProtocolVersion); ClientTypeAnnotation clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType())); using (ODataMessageWriter writer = CreateMessageWriter(requestMessage, this.requestInfo)) { ODataWriter odataWriter = writer.CreateODataEntryWriter(); ODataEntry entry = new ODataEntry(); if (this.requestInfo.HasWritingEventHandlers) { entry.SetAnnotation <WritingEntityInfo>(new WritingEntityInfo(entityDescriptor.Entity, this.requestInfo)); } string serverTypeName = this.requestInfo.GetServerTypeName(entityDescriptor); if (clientTypeAnnotation.ElementTypeName != serverTypeName) { SerializationTypeNameAnnotation annotation = new SerializationTypeNameAnnotation { TypeName = serverTypeName }; entry.SetAnnotation <SerializationTypeNameAnnotation>(annotation); } entry.TypeName = clientTypeAnnotation.ElementTypeName; if (EntityStates.Modified == entityDescriptor.State) { entry.Id = entityDescriptor.GetLatestIdentity(); } if (entityDescriptor.IsMediaLinkEntry || clientTypeAnnotation.IsMediaLinkEntry) { entry.MediaResource = new ODataStreamReferenceValue(); } odataWriter.WriteStart(entry); if (EntityStates.Added == entityDescriptor.State) { this.WriteNavigationLink(entityDescriptor, relatedLinks, odataWriter); } entry.Properties = this.PopulateProperties(clientTypeAnnotation, entityDescriptor.Entity, null); odataWriter.WriteEnd(); } }
/// <summary> /// Returns the new XmlReader to cache the payload for firing ReadingEntity event. /// </summary> /// <param name="entry">ODataEntry instance that is currently getting deserialized.</param> /// <param name="entryReader">XmlReader that is used to read the payload.</param> /// <param name="baseUri">BaseUri for the entry payload.</param> /// <returns>XmlReader instance that needs to be used to read the payload for the given odataentry.</returns> internal static XmlReader BufferAndCacheEntryPayload(ODataEntry entry, XmlReader entryReader, Uri baseUri) { XElement entryPayload = XElement.Load(entryReader.ReadSubtree(), LoadOptions.None); // Move the parent entry reader after the end element of the entry. entryReader.Read(); entry.SetAnnotation(new ReadingEntityInfo(entryPayload, baseUri)); XmlReader xmlReader = entryPayload.CreateReader(); xmlReader.Read(); return(xmlReader); }
public static AtomEntryMetadata Atom(this ODataEntry entry) { ExceptionUtils.CheckArgumentNotNull(entry, "entry"); AtomEntryMetadata entryMetadata = entry.GetAnnotation <AtomEntryMetadata>(); if (entryMetadata == null) { entryMetadata = new AtomEntryMetadata(); entry.SetAnnotation(entryMetadata); } return(entryMetadata); }
internal void SetTypeName(ODataEntry entry, string entitySetBaseTypeName, string entryTypeName) { Debug.Assert(entry != null, "entry != null"); // We should always write this since for derived types, ODL needs to know the typename. entry.TypeName = entryTypeName; if (this.interpreter.ShouldIncludeEntryTypeName(entitySetBaseTypeName, entryTypeName)) { entry.SetAnnotation(new SerializationTypeNameAnnotation() { TypeName = entry.TypeName }); } else { // When we should not write the typename, setting the serialization type name to null // so that ODL does not write the type on the wire. entry.SetAnnotation(new SerializationTypeNameAnnotation() { TypeName = null }); } }
public static MaterializerEntry CreateEntry(ODataEntry entry, DataServiceProtocolVersion maxProtocolVersion) { MaterializerEntry annotation = new MaterializerEntry(entry, maxProtocolVersion); entry.SetAnnotation <MaterializerEntry>(annotation); if (entry.Id == null) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Deserialize_MissingIdElement); } annotation.EntityDescriptor.Identity = entry.Id; annotation.EntityDescriptor.EditLink = entry.EditLink; annotation.EntityDescriptor.SelfLink = entry.ReadLink; annotation.EntityDescriptor.ETag = entry.ETag; return(annotation); }
private static void WriteOdataEntity(ITableEntity entity, TableOperationType operationType, OperationContext ctx, ODataWriter writer, TableRequestOptions options) { ODataEntry entry = new ODataEntry() { Properties = GetPropertiesWithKeys(entity, ctx, operationType, options), TypeName = "account.sometype" }; entry.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = null }); writer.WriteStart(entry); writer.WriteEnd(); writer.Flush(); }
internal static IEdmValue CreateStructuredEdmValue(ODataEntry entry, IEdmEntitySet entitySet, IEdmEntityTypeReference entityType) { if (entitySet != null) { object typeAnnotation = ReflectionUtils.CreateInstance( odataTypeAnnotationType, new Type[] { typeof(IEdmEntitySet), typeof(IEdmEntityTypeReference) }, entitySet, entityType); entry.SetAnnotation(typeAnnotation); } return((IEdmValue)ReflectionUtils.CreateInstance( odataEdmStructuredValueType, new Type[] { typeof(ODataEntry) }, entry)); }
public override void Annotate(HttpRequestMessage request, ODataEntry entry, object entityInstance) { var feedPackage = entityInstance as V2FeedPackage; if (feedPackage == null) { return; } // Patch links to use normalized versions var normalizedVersion = NuGetVersionFormatter.Normalize(feedPackage.Version); NormalizeNavigationLinks(entry, request, feedPackage, normalizedVersion); // Set Atom entry metadata var atomEntryMetadata = new AtomEntryMetadata(); atomEntryMetadata.Title = feedPackage.Title; if (!string.IsNullOrEmpty(feedPackage.Authors)) { atomEntryMetadata.Authors = new[] { new AtomPersonMetadata { Name = feedPackage.Authors } }; } if (feedPackage.LastUpdated > DateTime.MinValue) { atomEntryMetadata.Updated = feedPackage.LastUpdated; } if (!string.IsNullOrEmpty(feedPackage.Summary)) { atomEntryMetadata.Summary = feedPackage.Summary; } entry.SetAnnotation(atomEntryMetadata); // Add package download link entry.MediaResource = new ODataStreamReferenceValue { ContentType = ContentType, ReadLink = BuildLinkForStreamProperty("v2", feedPackage.Id, normalizedVersion, request) }; }
private static void WriteOdataEntity(ITableEntity entity, TableOperationType operationType, OperationContext ctx, ODataWriter writer) { ODataEntry entry = new ODataEntry() { Properties = GetPropertiesWithKeys(entity, ctx, operationType), TypeName = "account.sometype" }; if (operationType != TableOperationType.Insert && operationType != TableOperationType.Retrieve) { entry.ETag = entity.ETag; } entry.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = null }); writer.WriteStart(entry); writer.WriteEnd(); writer.Flush(); }
private static void WriteEntry(ODataWriter writer, object entity, IEnumerable <string> projectedProperties) { var entry = new ODataEntry() { Id = new Uri("http://temp.org/" + Guid.NewGuid()), SerializationInfo = MySerializationInfo }; if (projectedProperties != null) { entry.SetAnnotation <ProjectedPropertiesAnnotation>(new ProjectedPropertiesAnnotation(projectedProperties)); } entry.Properties = entity.GetType().GetProperties().Select(p => new ODataProperty() { Name = p.Name, Value = p.GetValue(entity, null) }); writer.WriteStart(entry); writer.WriteEnd(); }
private static ODataEntry CreateEntryWithKeyAsSegmentConvention(bool addAnnotation, bool?useKeyAsSegment) { var model = new EdmModel(); var container = new EdmEntityContainer("Fake", "Container"); model.AddElement(container); if (addAnnotation) { model.AddVocabularyAnnotation(new EdmAnnotation(container, UrlConventionsConstants.ConventionTerm, UrlConventionsConstants.KeyAsSegmentAnnotationValue)); } EdmEntityType entityType = new EdmEntityType("Fake", "FakeType"); entityType.AddKeys(entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); model.AddElement(entityType); var entitySet = new EdmEntitySet(container, "FakeSet", entityType); container.AddElement(entitySet); var metadataContext = new ODataMetadataContext( true, ODataReaderBehavior.DefaultBehavior.OperationsBoundToEntityTypeMustBeContainerQualified, new EdmTypeReaderResolver(model, ODataReaderBehavior.DefaultBehavior), model, new Uri("http://temp.org/$metadata"), null /*requestUri*/); var thing = new ODataEntry { Properties = new[] { new ODataProperty { Name = "Id", Value = 1 } } }; thing.SetAnnotation(new ODataTypeAnnotation(entitySet, entityType)); thing.MetadataBuilder = metadataContext.GetEntityMetadataBuilderForReader(new TestJsonLightReaderEntryState { Entry = thing, SelectedProperties = new SelectedPropertiesNode("*") }, useKeyAsSegment); return(thing); }
public void FlagsEnumAsEntityProperty_NullAsValue_ButNonNullable_GetNullError() { DateTimeOffset updatedTime = DateTimeOffset.UtcNow; Func<ODataEntry> entryClone = () => { var tmp = new ODataEntry { TypeName = "NS.MyEntityType", Properties = new[] { new ODataProperty { Name = "ColorFlags", Value = null } }, SerializationInfo = MySerializationInfo }; tmp.SetAnnotation(new AtomEntryMetadata() { Updated = updatedTime }); return tmp; }; string fullName = this.entityType.FindProperty("ColorFlags").Type.FullName(); // model-request Action action = () => this.WriteRequestWithModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: ""); action.ShouldThrow<ODataException>().WithMessage(Strings.WriterValidationUtils_NonNullablePropertiesMustNotHaveNullValue("ColorFlags", fullName)); // model-reseponse action = () => this.WriteResponseWithModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: ""); action.ShouldThrow<ODataException>().WithMessage(Strings.WriterValidationUtils_NonNullablePropertiesMustNotHaveNullValue("ColorFlags", fullName)); // NoModel-request string expectedPayload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" " + "xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://odata.org/test/$metadata#MySet/$entity\">" + "<category term=\"#NS.MyEntityType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />" + "<id />" + "<title />" + "<updated>" + ODataAtomConvert.ToAtomString(updatedTime) + "</updated>" + "<author><name /></author>" + "<content type=\"application/xml\">" + "<m:properties>" + "<d:ColorFlags m:null=\"true\" />" + "</m:properties>" + "</content>" + "</entry>"; this.WriteRequestWithoutModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // NoModel-response this.WriteResponseWithoutModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); }
private static void AddEntryMetadata(EntityInstance payloadElement, ODataEntry entry) { AtomEntryMetadata metadata = null; foreach (XmlTreeAnnotation epmTree in payloadElement.Annotations.OfType <XmlTreeAnnotation>()) { if (epmTree.NamespaceName == TestAtomConstants.AtomNamespace) { if (metadata == null) { metadata = new AtomEntryMetadata(); } string localName = epmTree.LocalName; if (localName == TestAtomConstants.AtomAuthorElementName) { Debug.Assert(!epmTree.IsAttribute); AtomPersonMetadata author = CreateAuthorMetadata(epmTree.Children); List <AtomPersonMetadata> authors; if (metadata.Authors == null) { authors = new List <AtomPersonMetadata>(); metadata.Authors = authors; } else { authors = (List <AtomPersonMetadata>)metadata.Authors; } authors.Add(author); } else if (localName == TestAtomConstants.AtomCategoryElementName) { Debug.Assert(!epmTree.IsAttribute); AtomCategoryMetadata category = CreateCategoryMetadata(epmTree.Children); List <AtomCategoryMetadata> categories; if (metadata.Categories == null) { categories = new List <AtomCategoryMetadata>(); metadata.Categories = categories; } else { categories = (List <AtomCategoryMetadata>)metadata.Categories; } categories.Add(category); } else if (localName == TestAtomConstants.AtomContributorElementName) { Debug.Assert(!epmTree.IsAttribute); AtomPersonMetadata contributor = CreateAuthorMetadata(epmTree.Children); List <AtomPersonMetadata> contributors; if (metadata.Contributors == null) { contributors = new List <AtomPersonMetadata>(); metadata.Contributors = contributors; } else { contributors = (List <AtomPersonMetadata>)metadata.Contributors; } contributors.Add(contributor); } else if (localName == TestAtomConstants.AtomIdElementName) { Debug.Assert(!epmTree.IsAttribute); entry.Id = string.IsNullOrEmpty(epmTree.PropertyValue) ? null : new Uri(epmTree.PropertyValue); } else if (localName == TestAtomConstants.AtomLinkElementName) { Debug.Assert(!epmTree.IsAttribute); AtomLinkMetadata link = CreateLinkMetadata(epmTree.Children); List <AtomLinkMetadata> links; if (metadata.Links == null) { links = new List <AtomLinkMetadata>(); metadata.Links = links; } else { links = (List <AtomLinkMetadata>)metadata.Links; } links.Add(link); } else if (localName == TestAtomConstants.AtomPublishedElementName) { Debug.Assert(!epmTree.IsAttribute); metadata.Published = string.IsNullOrEmpty(epmTree.PropertyValue) ? (DateTimeOffset?)null : DateTimeOffset.Parse(epmTree.PropertyValue); } else if (localName == TestAtomConstants.AtomRightsElementName) { Debug.Assert(!epmTree.IsAttribute); AtomTextConstructKind atomConstructKind = GetAtomConstructKind(epmTree.Children); metadata.Rights = new AtomTextConstruct { Kind = atomConstructKind, Text = epmTree.PropertyValue }; } else if (localName == TestAtomConstants.AtomSourceElementName) { Debug.Assert(!epmTree.IsAttribute); metadata.Source = CreateFeedMetadata(epmTree.Children, null); } else if (localName == TestAtomConstants.AtomSummaryElementName) { Debug.Assert(!epmTree.IsAttribute); AtomTextConstructKind atomConstructKind = GetAtomConstructKind(epmTree.Children); metadata.Summary = new AtomTextConstruct { Kind = atomConstructKind, Text = epmTree.PropertyValue }; } else if (localName == TestAtomConstants.AtomTitleElementName) { Debug.Assert(!epmTree.IsAttribute); AtomTextConstructKind atomConstructKind = GetAtomConstructKind(epmTree.Children); metadata.Title = new AtomTextConstruct { Kind = atomConstructKind, Text = epmTree.PropertyValue }; } else if (localName == TestAtomConstants.AtomUpdatedElementName) { Debug.Assert(!epmTree.IsAttribute); metadata.Updated = string.IsNullOrEmpty(epmTree.PropertyValue) ? (DateTimeOffset?)null : DateTimeOffset.Parse(epmTree.PropertyValue); } else { throw new NotSupportedException("Unsupported atom metadata '" + localName + "' found for entry!"); } } } // Fix up metadata for baselining metadata = metadata.Fixup(); if (metadata != null) { entry.SetAnnotation <AtomEntryMetadata>(metadata); } }
public void FlagsEnumAsEntityProperty_EmptyStrAsValue_NullAsTypeName() { DateTimeOffset updatedTime = DateTimeOffset.UtcNow; Func<ODataEntry> entryClone = () => { var tmp = new ODataEntry { TypeName = "NS.MyEntityType", Properties = new[] { new ODataProperty { Name = "ColorFlags", Value = new ODataEnumValue("") } }, SerializationInfo = MySerializationInfo }; tmp.SetAnnotation(new AtomEntryMetadata() { Updated = updatedTime }); return tmp; }; // model-request string expectedPayload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" " + "xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://odata.org/test/$metadata#MySet/$entity\">" + "<category term=\"#NS.MyEntityType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />" + "<id />" + "<title />" + "<updated>" + ODataAtomConvert.ToAtomString(updatedTime) + "</updated>" + "<author><name /></author>" + "<content type=\"application/xml\">" + "<m:properties>" + "<d:ColorFlags m:type=\"#NS.ColorFlags\"></d:ColorFlags>" + "</m:properties>" + "</content>" + "</entry>"; this.WriteRequestWithModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // model-reseponse this.WriteResponseWithModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // NoModel-request expectedPayload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" " + "xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://odata.org/test/$metadata#MySet/$entity\">" + "<category term=\"#NS.MyEntityType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />" + "<id />" + "<title />" + "<updated>" + ODataAtomConvert.ToAtomString(updatedTime) + "</updated>" + "<author><name /></author>" + "<content type=\"application/xml\">" + "<m:properties>" + "<d:ColorFlags></d:ColorFlags>" + "</m:properties>" + "</content>" + "</entry>"; this.WriteRequestWithoutModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // NoModel-response this.WriteResponseWithoutModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); }
/// <summary>Write the entry element.</summary> /// <param name="expanded">Expanded result provider for the specified <paramref name="element"/>.</param> /// <param name="element">Element representing the entry element.</param> /// <param name="resourceInstanceInFeed">true if the resource instance being serialized is inside a feed; false otherwise.</param> /// <param name="expectedType">Expected type of the entry element.</param> private void WriteEntry(IExpandedResult expanded, object element, bool resourceInstanceInFeed, ResourceType expectedType) { Debug.Assert(element != null, "element != null"); Debug.Assert(expectedType != null && expectedType.ResourceTypeKind == ResourceTypeKind.EntityType, "expectedType != null && expectedType.ResourceTypeKind == ResourceTypeKind.EntityType"); this.IncrementSegmentResultCount(); ODataEntry entry = new ODataEntry(); if (!resourceInstanceInFeed) { entry.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = this.CurrentContainer.Name, NavigationSourceEntityTypeName = this.CurrentContainer.ResourceType.FullName, ExpectedTypeName = expectedType.FullName }); } string title = expectedType.Name; #pragma warning disable 618 if (this.contentFormat == ODataFormat.Atom) #pragma warning restore 618 { AtomEntryMetadata entryAtom = new AtomEntryMetadata(); entryAtom.EditLink = new AtomLinkMetadata { Title = title }; entry.SetAnnotation(entryAtom); } ResourceType actualResourceType = WebUtil.GetNonPrimitiveResourceType(this.Provider, element); if (actualResourceType.ResourceTypeKind != ResourceTypeKind.EntityType) { // making sure that the actual resource type is an entity type throw new DataServiceException(500, Microsoft.OData.Service.Strings.BadProvider_InconsistentEntityOrComplexTypeUsage(actualResourceType.FullName)); } EntityToSerialize entityToSerialize = this.WrapEntity(element, actualResourceType); // populate the media resource, if the entity is a MLE. entry.MediaResource = this.GetMediaResource(entityToSerialize, title); // Write the type name this.PayloadMetadataPropertyManager.SetTypeName(entry, this.CurrentContainer.ResourceType.FullName, actualResourceType.FullName); // Write Id element this.PayloadMetadataPropertyManager.SetId(entry, () => entityToSerialize.SerializedKey.Identity); // Write "edit" link this.PayloadMetadataPropertyManager.SetEditLink(entry, () => entityToSerialize.SerializedKey.RelativeEditLink); // Write the etag property, if the type has etag properties this.PayloadMetadataPropertyManager.SetETag(entry, () => this.GetETagValue(element, actualResourceType)); IEnumerable <ProjectionNode> projectionNodes = this.GetProjections(); if (projectionNodes != null) { // Filter the projection nodes for the actual type of the entity // The projection node might refer to the property in a derived type. If the TargetResourceType of // the projection node is not a super type, then we do not want to serialize this property. projectionNodes = projectionNodes.Where(projectionNode => projectionNode.TargetResourceType.IsAssignableFrom(actualResourceType)); // Because we are going to enumerate through these multiple times, create a list. projectionNodes = projectionNodes.ToList(); // And add the annotation to tell ODataLib which properties to write into content (the projections) entry.SetAnnotation(new ProjectedPropertiesAnnotation(projectionNodes.Select(p => p.PropertyName))); } // Populate the advertised actions IEnumerable <ODataAction> actions; if (this.TryGetAdvertisedActions(entityToSerialize, resourceInstanceInFeed, out actions)) { foreach (ODataAction action in actions) { entry.AddAction(action); } } // Populate all the normal properties entry.Properties = this.GetEntityProperties(entityToSerialize, projectionNodes); // And start the entry var args = new DataServiceODataWriterEntryArgs(entry, element, this.Service.OperationContext); this.dataServicesODataWriter.WriteStart(args); // Now write all the navigation properties this.WriteNavigationProperties(expanded, entityToSerialize, resourceInstanceInFeed, projectionNodes); // And write the end of the entry this.dataServicesODataWriter.WriteEnd(args); #if ASTORIA_FF_CALLBACKS this.Service.InternalOnWriteItem(target, element); #endif }
private IEnumerable <ODataItem> CreatePayload(ProjectedPropertiesTestCase testCase) { // First create the entry itself (it might get wrapped later) ODataEntry entry = new ODataEntry() { TypeName = "TestModel.EntityType", Properties = new List <ODataProperty>() { new ODataProperty { Name = "StringProperty", Value = "foo" }, new ODataProperty { Name = "NumberProperty", Value = 42 }, new ODataProperty { Name = "SimpleComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.SimplexComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "Name", Value = "Bart" } } } }, new ODataProperty { Name = "DeepComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.NestedComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "InnerComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.SimplexComplexType2", Properties = new ODataProperty[] { new ODataProperty { Name = "Value", Value = 43 } } } } } } }, new ODataProperty { Name = "PrimitiveCollection", Value = new ODataCollectionValue { TypeName = "Collection(Edm.String)", Items = new object[] { "Simpson" } } }, new ODataProperty { Name = "ComplexCollection", Value = new ODataCollectionValue { TypeName = "Collection(TestModel.RatingComplexType)", Items = new object[] { new ODataComplexValue { TypeName = "TestModel.RatingComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "Rating", Value = -3 } } } } } } }, SerializationInfo = MySerializationInfo }; if (testCase.ResponseOnly) { // Add a stream property for responses ((List <ODataProperty>)entry.Properties).Add(new ODataProperty { Name = "NamedStream", Value = new ODataStreamReferenceValue { EditLink = new Uri("http://odata.org/namedstream") } }); } ODataItem[] entryItems = new ODataItem[] { entry, new ODataNavigationLink { Name = "DeferredNavigation", IsCollection = false, Url = new Uri("http://odata.org/deferred"), AssociationLinkUrl = testCase.ResponseOnly ? new Uri("http://odata.org/associationlink2") : null }, null, // End deferred link new ODataNavigationLink { Name = "ExpandedEntry", IsCollection = false, Url = new Uri("http://odata.org/entry") }, new ODataEntry() { TypeName = "TestModel.ExpandedEntryType", Properties = new ODataProperty[] { new ODataProperty { Name = "ExpandedEntryName", Value = "bar" } }, SerializationInfo = MySerializationInfo }, new ODataNavigationLink { Name = "ExpandedEntry_DeferredNavigation", IsCollection = false, Url = new Uri("http://odata.org/deferred") }, null, // End deffered link new ODataNavigationLink { Name = "ExpandedEntry_ExpandedFeed", IsCollection = true, Url = new Uri("http://odata.org/feed") }, new ODataFeed { Id = new Uri("http://test/feedid1"), SerializationInfo = MySerializationInfo }, null, // End feed null, // End exanded expanded feed link null, // End expanded entry null, // End expanded entry nav link new ODataNavigationLink { Name = "ExpandedFeed", IsCollection = true, Url = new Uri("http://odata.org/feed") }, new ODataFeed { Id = new Uri("http://test/feedid2") }, new ODataEntry { TypeName = "TestModel.EntityType" }, null, // End entry new ODataEntry { TypeName = "TestModel.EntityType", SerializationInfo = MySerializationInfo }, null, // End entry null, // End expanded feed null, // End expanded feed nav link null, // End the top-level entry }; ProjectedPropertiesAnnotation projectedProperties = testCase.TopLevelProjectedProperties; if (!testCase.NestedPayload) { this.Assert.IsNull(testCase.NestedProjectedProperties, "For a non-nested payload, no nested annotation must be specified."); entry.SetAnnotation(projectedProperties); return(entryItems); } // If we are processing a test case for a nested payload, wrap the entry items into a wrapping entry with an expanded navigation link. ODataEntry wrappingEntry = new ODataEntry() { TypeName = "TestModel.WrappingEntityType", Properties = new[] { new ODataProperty { Name = "Wrapping_ID", Value = 1 } }, SerializationInfo = MySerializationInfo }; IEnumerable <ODataItem> wrappedItems = new ODataItem[] { wrappingEntry, new ODataNavigationLink { Name = "Wrapping_ExpandedEntry", IsCollection = false, Url = new Uri("http://odata.org/wrapping") } } .Concat(entryItems) .Concat(new ODataItem[] { null, null }); ProjectedPropertiesAnnotation nestedProjectedProperties = testCase.NestedProjectedProperties; entry.SetAnnotation(nestedProjectedProperties); wrappingEntry.SetAnnotation(projectedProperties); return(wrappedItems); }
public void FlagsEnumAsComplexProperty_StrAsValue_StrAsTypeName() { DateTimeOffset updatedTime = DateTimeOffset.UtcNow; Func<ODataEntry> entryClone = () => { var tmp = new ODataEntry { TypeName = "NS.MyEntityType", Properties = new[] { new ODataProperty{Name = "FloatId", Value = new ODataPrimitiveValue(12.3D)}, new ODataProperty{Name = "Color", Value = new ODataEnumValue(Color.Green.ToString(), "NS.Color")}, new ODataProperty { Name = "MyComplexType", Value = new ODataComplexValue { Properties = new[] { new ODataProperty { Name = "MyColorFlags", Value = new ODataEnumValue(Color.Red.ToString(), "NS.EnumUndefinedTypename") }, new ODataProperty { Name = "Height", Value = 98.6 }} } } }, SerializationInfo = MySerializationInfo }; tmp.SetAnnotation(new AtomEntryMetadata() { Updated = updatedTime }); return tmp; }; // model-request string expectedPayload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://odata.org/test/$metadata#MySet/$entity\">" + "<category term=\"#NS.MyEntityType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />" + "<id />" + "<title />" + "<updated>" + ODataAtomConvert.ToAtomString(updatedTime) + "</updated>" + "<author>" + "<name />" + "</author>" + "<content type=\"application/xml\">" + "<m:properties>" + "<d:FloatId m:type=\"Double\">12.3</d:FloatId>" + "<d:Color m:type=\"#NS.Color\">Green</d:Color>" + "<d:MyComplexType m:type=\"#NS.MyComplexType\">" + "<d:MyColorFlags m:type=\"#NS.EnumUndefinedTypename\">Red</d:MyColorFlags>" + "<d:Height m:type=\"Double\">98.6</d:Height>" + "</d:MyComplexType>" + "</m:properties>" + "</content>" + "</entry>"; this.WriteRequestWithModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // model-reseponse this.WriteResponseWithModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // NoModel-request expectedPayload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://odata.org/test/$metadata#MySet/$entity\">" + "<category term=\"#NS.MyEntityType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />" + "<id />" + "<title />" + "<updated>" + ODataAtomConvert.ToAtomString(updatedTime) + "</updated>" + "<author>" + "<name />" + "</author>" + "<content type=\"application/xml\">" + "<m:properties>" + "<d:FloatId m:type=\"Double\">12.3</d:FloatId>" + "<d:Color m:type=\"#NS.Color\">Green</d:Color>" + "<d:MyComplexType>" + "<d:MyColorFlags m:type=\"#NS.EnumUndefinedTypename\">Red</d:MyColorFlags>" + "<d:Height m:type=\"Double\">98.6</d:Height>" + "</d:MyComplexType>" + "</m:properties>" + "</content>" + "</entry>"; this.WriteRequestWithoutModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); // NoModel-response this.WriteResponseWithoutModelAndValidatePayload(nestedItemToWrite: new[] { entryClone() }, expectedPayload: expectedPayload); }