Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MaterializedEntityArgs"/> class.
 /// </summary>
 /// <param name="entry">The entry.</param>
 /// <param name="entity">The entity.</param>
 public MaterializedEntityArgs(ODataEntry entry, object entity)
 {
     Util.CheckArgumentNull(entry, "entry");
     Util.CheckArgumentNull(entity, "entity");
     this.Entry = entry;
     this.Entity = entity;
 }
        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;
        }
 /// <summary>
 /// Creates a new instance of DataServiceODataWriterEntryArgs
 /// </summary>
 /// <param name="entry">ODataEntry instance.</param>
 /// <param name="entityInstance">Entity instance that is getting serialized.</param>
 /// <param name="operationContext">DataServiceOperationContext instance.</param>
 public DataServiceODataWriterEntryArgs(ODataEntry entry, object entityInstance, DataServiceOperationContext operationContext)
 {
     Debug.Assert(operationContext != null, "operationContext != null");
     this.Entry = entry;
     this.Instance = entityInstance;
     this.OperationContext = operationContext;
 }
        /// <summary>
        /// Converts an item from the data store into an ODataEntry.
        /// </summary>
        /// <param name="element">The item to convert.</param>
        /// <param name="entitySet">The entity set that the item belongs to.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <returns>The converted ODataEntry.</returns>
        public static ODataEntry ConvertToODataEntry(object element, IEdmEntitySet entitySet, ODataVersion targetVersion)
        {
            IEdmEntityType entityType = entitySet.EntityType();

            Uri entryUri = BuildEntryUri(element, entitySet, targetVersion);

            var entry = new ODataEntry
            {
                // writes out the edit link including the service base uri  , e.g.: http://<serviceBase>/Customers('ALFKI')
                EditLink = entryUri,

                // writes out the self link including the service base uri  , e.g.: http://<serviceBase>/Customers('ALFKI')
                ReadLink = entryUri,

                // we use the EditLink as the Id for this entity to maintain convention,
                Id = entryUri,

                // writes out the <category term='Customer'/> element 
                TypeName = element.GetType().Namespace + "." + entityType.Name,

                Properties = entityType.StructuralProperties().Select(p => ConvertToODataProperty(element, p.Name)),
            };

            return entry;
        }
 public void TestInit()
 {
     this.entry = new ODataEntry {TypeName = ActualEntityType.FullName()};
     this.typeContext = new TestFeedAndEntryTypeContext();
     this.entryMetadataContextWithoutModel = ODataEntryMetadataContext.Create(this.entry, this.typeContext, new ODataFeedAndEntrySerializationInfo(), /*actualEntityType*/null, new TestMetadataContext(), SelectedPropertiesNode.EntireSubtree);
     this.entryMetadataContextWithModel = ODataEntryMetadataContext.Create(this.entry, this.typeContext, /*serializationInfo*/null, ActualEntityType, new TestMetadataContext(), SelectedPropertiesNode.EntireSubtree);
 }
Пример #6
0
        private ODataEntry CreateEntry(int dataSizeKb)
        {
            var entry = new ODataEntry
            {
                Id = new Uri("http://www.odata.org/Perf.svc/Item(1)"),
                EditLink = new Uri("Item(1)", UriKind.Relative),
                ReadLink = new Uri("Item(1)", UriKind.Relative),
                TypeName = "PerformanceServices.Edm.ExchangeAttachment.Item",
                Properties = new[]
                    {
                        new ODataProperty{ Name = "HasAttachments", Value = false},
                        new ODataProperty{ Name = "Attachments", Value = new ODataCollectionValue
                            {
                                TypeName = "Collection(PerformanceServices.Edm.ExchangeAttachment.Attachment)",
                                Items = dataSizeKb == 0 ? new ODataComplexValue[0]: 
                                Enumerable.Range(0, 1).Select(n => new ODataComplexValue
                                {
                                    TypeName = "PerformanceServices.Edm.ExchangeAttachment.Attachment",
                                    Properties = new[]
                                    {
                                        new ODataProperty { Name = "Name", Value = "attachment" },
                                        new ODataProperty { Name = "IsInline", Value = false },
                                        new ODataProperty { Name = "LastModifiedTime", Value = new DateTimeOffset(1987, 6, 5, 4, 3, 21, 0, new TimeSpan(0, 0, 3, 0)) },
                                        new ODataProperty { Name = "Content", Value = new byte[dataSizeKb * 1024]}, 
                                    }
                                })
                            }}
                    }
            };

            return entry;
        }
Пример #7
0
        /// <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.Fail("Test only currently supports creating ODataEntry from IEdmPrimitiveValue instances.");
                    return null;
                }

                return new ODataProperty() { Name = p.Name, Value = propertyValue };
            });

            return entry;
        }
        public void WriteCompletedAsyncResponse()
        {
            var asyncWriter = this.TestInit();

            var innerMessage = asyncWriter.CreateResponseMessage();
            innerMessage.StatusCode = 200;
            innerMessage.SetHeader("Content-Type", "application/json");

            var settings = new ODataMessageWriterSettings();
            settings.SetServiceDocumentUri(new Uri(ServiceDocumentUri));
            settings.DisableMessageStreamDisposal = true;

            using (var innerMessageWriter = new ODataMessageWriter(innerMessage, settings, this.userModel))
            {
                var entryWriter = innerMessageWriter.CreateODataEntryWriter(singleton, testType);
                var entry = new ODataEntry() {TypeName = "NS.Test", Properties = new[] {new ODataProperty() {Name = "Id", Value = 1}}};
                entryWriter.WriteStart(entry);
                entryWriter.WriteEnd();
            }

            asyncWriter.Flush();

            var payload = this.TestFinish();
            Assert.AreEqual("HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nOData-Version: 4.0\r\n\r\n{\"@odata.context\":\"http://host/service/$metadata#MySingleton\",\"Id\":1}", payload);
        }
Пример #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="WritingEntryArgs"/> class.
 /// </summary>
 /// <param name="entry">The entry.</param>
 /// <param name="entity">The entity.</param>
 public WritingEntryArgs(ODataEntry entry, object entity)
 {
     Util.CheckArgumentNull(entry, "entry");
     Util.CheckArgumentNull(entity, "entity");
     this.Entry = entry;
     this.Entity = entity;
 }
        public void InitTest()
        {
            this.navigationLink = new ODataNavigationLink();

            var entry = new ODataEntry
            {
                TypeName = "ns.DerivedType",
                Properties = new[]
                {
                    new ODataProperty{Name = "Id", Value = 1, SerializationInfo = new ODataPropertySerializationInfo{PropertyKind = ODataPropertyKind.Key}},
                    new ODataProperty{Name = "Name", Value = "Bob", SerializationInfo = new ODataPropertySerializationInfo{PropertyKind = ODataPropertyKind.ETag}}
                }
            };

            var serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Set", NavigationSourceEntityTypeName = "ns.BaseType", ExpectedTypeName = "ns.BaseType" };
            var typeContext = ODataFeedAndEntryTypeContext.Create(serializationInfo, null, null, null, EdmCoreModel.Instance, true);
            var metadataContext = new TestMetadataContext();
            var entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, serializationInfo, null, metadataContext, SelectedPropertiesNode.EntireSubtree);
            var metadataBuilder = new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, new ODataConventionalUriBuilder(ServiceUri, UrlConvention.CreateWithExplicitValue(false)));
            this.navigationLinkWithFullBuilder = new ODataNavigationLink { Name = "NavProp" };
            this.navigationLinkWithFullBuilder.MetadataBuilder = metadataBuilder;

            this.navigationLinkWithNoOpBuilder = new ODataNavigationLink { Name = "NavProp" };
            this.navigationLinkWithNoOpBuilder.MetadataBuilder = new NoOpEntityMetadataBuilder(entry);

            this.navigationLinkWithNullBuilder = new ODataNavigationLink { Name = "NavProp" };
            this.navigationLinkWithNullBuilder.MetadataBuilder = ODataEntityMetadataBuilder.Null;
        }
 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.AreEqual(expected, actual);
 }
Пример #12
0
 /// <summary>
 /// This method is used to do some customerization according to the incoming headers.
 /// </summary>
 /// <param name="incomingHeaders">The headers in the request.</param>
 /// <param name="entry">The entry that need to customize.</param>
 private static void CustomizeEntry(Dictionary<string, string> incomingHeaders, ODataEntry entry)
 {
     if (null != incomingHeaders)
     {
         var stringOfKey = "Test_ODataEntryFieldToModify";
         if (incomingHeaders.ContainsKey(stringOfKey))
         {
             var longOfCurrentTime = DateTime.UtcNow.Ticks;
             var uri = new Uri("http://potato" + longOfCurrentTime);//create a URL that points to a none exist host
             var stringOfValue = incomingHeaders[stringOfKey];
             if (stringOfValue.Equals("EditLink", StringComparison.CurrentCultureIgnoreCase))
             {
                 entry.EditLink = uri;
             }
             else if (stringOfValue.Equals("ReadLink", StringComparison.CurrentCultureIgnoreCase))
             {
                 entry.ReadLink = uri;
             }
             else if (stringOfValue.Equals("Id", StringComparison.CurrentCultureIgnoreCase))
             {
                 entry.Id = uri;
             }
             else if (stringOfValue.Equals("IsTransient", StringComparison.CurrentCultureIgnoreCase))
             {
                 entry.IsTransient = true;
             }
             else if (stringOfValue.Equals("ReadOnly", StringComparison.CurrentCultureIgnoreCase))
             {
                 entry.ReadLink = new Uri("People(1)", UriKind.Relative);
                 entry.EditLink = null;
             }
         }
     }
 }
        public void EntryMetadataUrlRoundTrip()
        {
            var stream = new MemoryStream();
            var writerRequestMemoryMessage = new InMemoryMessage();
            writerRequestMemoryMessage.Stream = stream;
            writerRequestMemoryMessage.SetHeader("Content-Type", "application/json");

            var writerSettings = new ODataMessageWriterSettings() {Version = ODataVersion.V4, DisableMessageStreamDisposal = true};
            writerSettings.ODataUri = new ODataUri() {ServiceRoot = new Uri("http://christro.svc/")};

            var messageWriter = new ODataMessageWriter((IODataResponseMessage)writerRequestMemoryMessage, writerSettings, this.model);
            var organizationSetWriter = messageWriter.CreateODataEntryWriter(this.organizationsSet);
            var odataEntry = new ODataEntry(){ TypeName = ModelNamespace + ".Corporation" };
            odataEntry.Property("Id", 1);
            odataEntry.Property("Name", "");
            odataEntry.Property("TickerSymbol", "MSFT");

            organizationSetWriter.WriteStart(odataEntry);
            organizationSetWriter.WriteEnd();

            var readerPayloadInput = Encoding.UTF8.GetString(stream.GetBuffer());
            Console.WriteLine(readerPayloadInput);

            var readerResponseMemoryMessage = new InMemoryMessage();
            readerResponseMemoryMessage.Stream = new MemoryStream(stream.GetBuffer());
            readerResponseMemoryMessage.SetHeader("Content-Type", "application/json");

            var messageReader = new ODataMessageReader((IODataResponseMessage)readerResponseMemoryMessage, new ODataMessageReaderSettings() {MaxProtocolVersion = ODataVersion.V4, DisableMessageStreamDisposal = true}, this.model);
            var organizationReader = messageReader.CreateODataEntryReader(this.organizationsSet, this.organizationsSet.EntityType());
            organizationReader.Read().Should().Be(true);
            organizationReader.Item.As<ODataEntry>();
        }
 public void InjectMetadataBuilderShouldNotSetBuilderOnEntry()
 {
     var entry = new ODataEntry();
     var builder = new TestEntityMetadataBuilder(entry);
     testSubject.InjectMetadataBuilder(entry, builder);
     entry.MetadataBuilder.Should().BeOfType<NoOpEntityMetadataBuilder>();
 }
        private ODataEntryAnnotations CreateAnnotations(Microsoft.OData.Core.ODataEntry odataEntry)
        {
            string id       = null;
            Uri    readLink = null;
            Uri    editLink = null;

            if (_session.Adapter.GetMetadata().IsTypeWithId(odataEntry.TypeName))
            {
                try
                {
                    id       = odataEntry.Id.AbsoluteUri;
                    readLink = odataEntry.ReadLink;
                    editLink = odataEntry.EditLink;
                }
                catch (Exception)
                {
                    // Ingored
                }
            }

            return(new ODataEntryAnnotations
            {
                Id = id,
                TypeName = odataEntry.TypeName,
                ReadLink = readLink,
                EditLink = editLink,
                ETag = odataEntry.ETag,
                MediaResource = CreateAnnotations(odataEntry.MediaResource),
                InstanceAnnotations = odataEntry.InstanceAnnotations,
            });
        }
 public void InjectMetadataBuilderShouldSetBuilderOnEntry()
 {
     var entry = new ODataEntry();
     var builder = new TestEntityMetadataBuilder(entry);
     testSubject.InjectMetadataBuilder(entry, builder);
     entry.MetadataBuilder.Should().BeSameAs(builder);
 }
        public void ShortIntegrationTestToValidateEntryShouldBeRead()
        {
            var odataEntry = new ODataEntry() { Id = new Uri("http://services.odata.org/OData/OData.svc/Customers(0)") };
            odataEntry.Properties = new ODataProperty[] { new ODataProperty() { Name = "ID", Value = 0 }, new ODataProperty() { Name = "Description", Value = "Simple Stuff" } };

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

            var entriesMaterializer = new ODataEntriesEntityMaterializer(new ODataEntry[] { odataEntry }, materializerContext, adapter, components, typeof(Customer), null, ODataFormat.Atom);
            
            var customersRead = new List<Customer>();

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

            customersRead.Should().HaveCount(1);
            customersRead[0].ID.Should().Be(0);
            customersRead[0].Description.Should().Be("Simple Stuff");
        }
Пример #18
0
        /// <summary>Runs this plan.</summary>
        /// <param name="materializer">Materializer under which materialization should happen.</param>
        /// <param name="entry">Root entry to materialize.</param>
        /// <param name="expectedType">Expected type for the <paramref name="entry"/>.</param>
        /// <returns>The materialized object.</returns>
        internal object Run(ODataEntityMaterializer materializer, ODataEntry entry, Type expectedType)
        {
            Debug.Assert(materializer != null, "materializer != null");
            Debug.Assert(entry != null, "entry != null");

            return this.Plan(materializer, entry, expectedType);
        }
 public void InjectMetadataBuilderShouldNotSetBuilderOnEntryMediaResource()
 {
     var entry = new ODataEntry();
     var builder = new TestEntityMetadataBuilder(entry);
     entry.MediaResource = new ODataStreamReferenceValue();
     testSubject.InjectMetadataBuilder(entry, builder);
     entry.MediaResource.GetMetadataBuilder().Should().BeNull();
 }
 public void ShouldBeAbleToWriteTransientEntry()
 {
     IEdmEntityType entityType = GetEntityType();
     IEdmEntitySet entitySet = GetEntitySet(entityType);
     ODataEntry transientEntry = new ODataEntry() { IsTransient = true };
     var actual = WriteJsonLightEntry(true, null, false, transientEntry, entitySet, entityType);
     actual.Should().Contain("\"@odata.id\":null");
 }
 internal void SetId(ODataEntry entry, Func<Uri> computeIdentity)
 {
     Debug.Assert(entry != null, "entry != null");
     if (this.interpreter.ShouldIncludeEntryMetadata(PayloadMetadataKind.Entry.Id))
     {
         entry.Id = computeIdentity();
     }
 }
 internal void SetETag(ODataEntry entry, Func<string> computeETag)
 {
     Debug.Assert(entry != null, "entry != null");
     if (this.interpreter.ShouldIncludeEntryMetadata(PayloadMetadataKind.Entry.ETag))
     {
         entry.ETag = computeETag();
     }
 }
 public void GetIdShouldBeNullWhenEntryIsTransient()
 {
     Uri id = new Uri("http://example.com");
     ODataEntry odataEntry = new ODataEntry()
     {
         IsTransient = true,
         Id = id
     };
     new NoOpEntityMetadataBuilder(odataEntry).GetId().Should().BeNull();
 }
Пример #24
0
        public void ValidateNoMetadataShouldThrow()
        {
            var model = CreateTestModel();
            var coreWriter = CreateODataWriterCore(ODataFormat.Json, true, model, null, null, false);

            var entry = new ODataEntry();
            Action test = () => coreWriter.ValidateEntityType2(entry);

            test.ShouldThrow<ODataException>().WithMessage(Strings.WriterValidationUtils_MissingTypeNameWithMetadata);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="FeedAndEntryMaterializerAdapter"/> class. Used for tests so no ODataMessageReader is required
 /// </summary>
 /// <param name="odataFormat">The format of the reader.</param>
 /// <param name="reader">The reader.</param>
 /// <param name="model">The model.</param>
 /// <param name="mergeOption">The mergeOption.</param>
 internal FeedAndEntryMaterializerAdapter(ODataFormat odataFormat, ODataReaderWrapper reader, ClientEdmModel model, MergeOption mergeOption)
 {
     this.readODataFormat = odataFormat;
     this.clientEdmModel = model;
     this.mergeOption = mergeOption;
     this.reader = reader;
     this.currentEntry = null;
     this.currentFeed = null;
     this.feedEntries = null;
 }
Пример #26
0
        public void ValidateEntityTypeShouldAlwaysReturnSpecifiedTypeName()
        {
            var model = CreateTestModel();
            var set = model.EntityContainer.FindEntitySet("Objects");
            var objectType = (IEdmEntityType)model.FindDeclaredType("DefaultNamespace.Object");
            var coreWriter = CreateODataWriterCore(ODataFormat.Json, true, model, set, objectType, false);

            var entry = new ODataEntry() { TypeName = "DefaultNamespace.Person" };
            var entityType = coreWriter.ValidateEntityType2(entry);
            entityType.Should().BeSameAs(model.FindDeclaredType("DefaultNamespace.Person"));
        }
Пример #27
0
 public void DefaultValuesTest()
 {
     ODataEntry entry = new ODataEntry();
     this.Assert.IsNull(entry.ETag, "Expected null default value for property 'ETag'.");
     this.Assert.IsNull(entry.Id, "Expected null default value for property 'Id'.");
     this.Assert.IsNull(entry.EditLink, "Expected null default value for property 'EditLink'.");
     this.Assert.IsNull(entry.ReadLink, "Expected null default value for property 'ReadLink'.");
     this.Assert.IsNull(entry.Properties, "Expected null default value for property 'Properties'.");
     this.Assert.IsNull(entry.TypeName, "Expected null default value for property 'TypeName'.");
     this.Assert.IsNull(entry.MediaResource, "Expected null default value for property 'MediaResource'.");
 }
        private ODataEntry CreateEntryWithMaterializerEntry(ODataFormat format, object resolvedObject)
        {
            var entry = new ODataEntry();
            entry.Id = new Uri("http://www.odata.org/Northwind.Svc/Customer(1)");
            entry.Properties = new ODataProperty[] { new ODataProperty() { Name = "ID", Value = 1 } };

            var materializerEntry = MaterializerEntry.CreateEntry(entry, format, true, this.clientModel);
            materializerEntry.ResolvedObject = resolvedObject;

            return entry;
        }
Пример #29
0
        public void ValidateEntityTypeShouldReturnEntityTypeOfSet()
        {
            var model = CreateTestModel();
            var peopleSet = model.EntityContainer.FindEntitySet("People");
            var personType = (IEdmEntityType)model.FindDeclaredType("DefaultNamespace.Person");

            var coreWriter = CreateODataWriterCore(ODataFormat.Json, true, model, peopleSet, null, false);

            var entry = new ODataEntry();
            var entityType = coreWriter.ValidateEntityType2(entry);
            entityType.Should().BeSameAs(personType);
        }
        protected override async Task <Stream> WriteEntryContentAsync(string method, string collection, string commandText, IDictionary <string, object> entryData)
        {
            IODataRequestMessageAsync message = IsBatch
                ? await CreateOperationRequestMessageAsync(method, collection, entryData, commandText)
                : new ODataRequestMessage();

            var entityType = _model.FindDeclaredType(
                _session.Metadata.GetEntityCollectionQualifiedTypeName(collection)) as IEdmEntityType;
            var model = method == RestVerbs.Patch ? new EdmDeltaModel(_model, entityType, entryData.Keys) : _model;

            using (var messageWriter = new ODataMessageWriter(message, GetWriterSettings(), model))
            {
                if (method == RestVerbs.Get || method == RestVerbs.Delete)
                {
                    return(null);
                }

                var contentId = _deferredBatchWriter != null?_deferredBatchWriter.Value.GetContentId(entryData) : null;

                var entityCollection = _session.Metadata.GetEntityCollection(collection);
                var entryDetails     = _session.Metadata.ParseEntryDetails(entityCollection.Name, entryData, contentId);

                var entryWriter = await messageWriter.CreateODataEntryWriterAsync();

                var entry = new Microsoft.OData.Core.ODataEntry();
                entry.TypeName = entityType.FullName();

                var typeProperties = (_model.FindDeclaredType(entry.TypeName) as IEdmEntityType).Properties();

                entry.Properties = entryDetails.Properties.Select(x => new ODataProperty()
                {
                    Name  = typeProperties.BestMatch(y => y.Name, x.Key, _session.Pluralizer).Name,
                    Value = GetPropertyValue(typeProperties, x.Key, x.Value)
                }).ToList();

                await entryWriter.WriteStartAsync(entry);

                if (entryDetails.Links != null)
                {
                    foreach (var link in entryDetails.Links)
                    {
                        if (link.Value.Any(x => x.LinkData != null))
                        {
                            await WriteLinkAsync(entryWriter, entry, link.Key, link.Value);
                        }
                    }
                }

                await entryWriter.WriteEndAsync();

                return(IsBatch ? null : await message.GetStreamAsync());
            }
        }
        internal string GetEntryTypeNameForWriting(ODataEntry entry)
        {
            Debug.Assert(entry != null, "entry != null");

            SerializationTypeNameAnnotation typeNameAnnotation = entry.GetAnnotation<SerializationTypeNameAnnotation>();
            if (typeNameAnnotation != null)
            {
                return typeNameAnnotation.TypeName;
            }

            return entry.TypeName;
        }
        private byte[] ClientWriteAsyncBatchRequest()
        {
            var stream = new MemoryStream();

            IODataRequestMessage requestMessage = new InMemoryMessage { Stream = stream };
            requestMessage.SetHeader("Content-Type", batchContentType);

            using (var messageWriter = new ODataMessageWriter(requestMessage))
            {
                var batchWriter = messageWriter.CreateODataBatchWriter();

                batchWriter.WriteStartBatch();

                // Write a query operation.
                var queryOperationMessage = batchWriter.CreateOperationRequestMessage("GET", new Uri(serviceDocumentUri + "/Customers('ALFKI')"), /*contentId*/ null);

                // Write a changeset with multi update operation.
                batchWriter.WriteStartChangeset();

                // Create a creation operation in the changeset.
                var updateOperationMessage = batchWriter.CreateOperationRequestMessage("POST", new Uri(serviceDocumentUri + "/Customers"), "1");

                // Use a new message writer to write the body of this operation.
                using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage))
                {
                    var entryWriter = operationMessageWriter.CreateODataEntryWriter();
                    var entry = new ODataEntry() { TypeName = "MyNS.Customer", Properties = new[] { new ODataProperty() { Name = "Id", Value = "AFKIL" }, new ODataProperty() { Name = "Name", Value = "Bob" } } };
                    entryWriter.WriteStart(entry);
                    entryWriter.WriteEnd();
                }

                updateOperationMessage = batchWriter.CreateOperationRequestMessage("PATCH", new Uri(serviceDocumentUri + "/Customers('ALFKI')"), "2");

                using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage))
                {
                    var entryWriter = operationMessageWriter.CreateODataEntryWriter();
                    var entry = new ODataEntry() { TypeName = "MyNS.Customer", Properties = new[] { new ODataProperty() { Name = "Name", Value = "Jack" } } };
                    entryWriter.WriteStart(entry);
                    entryWriter.WriteEnd();
                }

                batchWriter.WriteEndChangeset();

                // Write a query operation.
                batchWriter.CreateOperationRequestMessage("GET", new Uri(serviceDocumentUri + "/Products"), /*contentId*/ null);

                batchWriter.WriteEndBatch();

                stream.Position = 0;
                return stream.ToArray();
            }
        }
        private async Task WriteLinkAsync(ODataWriter entryWriter, Microsoft.OData.Core.ODataEntry entry, string linkName, IEnumerable <ReferenceLink> links)
        {
            var navigationProperty = (_model.FindDeclaredType(entry.TypeName) as IEdmEntityType).NavigationProperties()
                                     .BestMatch(x => x.Name, linkName, _session.Pluralizer);
            bool isCollection = navigationProperty.Type.Definition.TypeKind == EdmTypeKind.Collection;

            var linkType        = GetNavigationPropertyEntityType(navigationProperty);
            var linkTypeWithKey = linkType;

            while (linkTypeWithKey.DeclaredKey == null && linkTypeWithKey.BaseEntityType() != null)
            {
                linkTypeWithKey = linkTypeWithKey.BaseEntityType();
            }

            await entryWriter.WriteStartAsync(new ODataNavigationLink()
            {
                Name         = linkName,
                IsCollection = isCollection,
                Url          = new Uri(ODataNamespace.Related + linkType, UriKind.Absolute),
            }).ConfigureAwait(false);

            foreach (var referenceLink in links)
            {
                var    linkKey   = linkTypeWithKey.DeclaredKey;
                var    linkEntry = referenceLink.LinkData.ToDictionary();
                var    contentId = GetContentId(referenceLink);
                string linkUri;
                if (contentId != null)
                {
                    linkUri = "$" + contentId;
                }
                else
                {
                    bool isSingleton;
                    var  formattedKey = _session.Adapter.GetCommandFormatter().ConvertKeyValuesToUriLiteral(
                        linkKey.ToDictionary(x => x.Name, x => linkEntry[x.Name]), true);
                    var linkedCollectionName = _session.Metadata.GetLinkedCollectionName(
                        referenceLink.LinkData.GetType().Name, linkTypeWithKey.Name, out isSingleton);
                    linkUri = linkedCollectionName + (isSingleton ? string.Empty : formattedKey);
                }
                var link = new ODataEntityReferenceLink
                {
                    Url = Utils.CreateAbsoluteUri(_session.Settings.BaseUri.AbsoluteUri, linkUri)
                };

                await entryWriter.WriteEntityReferenceLinkAsync(link).ConfigureAwait(false);
            }

            await entryWriter.WriteEndAsync().ConfigureAwait(false);
        }
        private async Task WriteLinkAsync(ODataWriter entryWriter, Microsoft.OData.Core.ODataEntry entry, string linkName, IEnumerable <ReferenceLink> links)
        {
            var navigationProperty = (_model.FindDeclaredType(entry.TypeName) as IEdmEntityType).NavigationProperties()
                                     .BestMatch(x => x.Name, linkName, _session.Pluralizer);
            bool isCollection = navigationProperty.Type.Definition.TypeKind == EdmTypeKind.Collection;

            var linkType = GetNavigationPropertyEntityType(navigationProperty);

            await entryWriter.WriteStartAsync(new ODataNavigationLink()
            {
                Name         = linkName,
                IsCollection = isCollection,
                Url          = new Uri("http://schemas.microsoft.com/ado/2007/08/dataservices/related/" + linkType, UriKind.Absolute),
            });

            foreach (var referenceLink in links)
            {
                var    linkKey   = linkType.DeclaredKey;
                var    linkEntry = referenceLink.LinkData.ToDictionary();
                var    contentId = GetContentId(referenceLink);
                string linkUri;
                if (contentId != null)
                {
                    linkUri = "$" + contentId;
                }
                else
                {
                    var linkSet = _model.SchemaElements
                                  .Where(x => x.SchemaElementKind == EdmSchemaElementKind.EntityContainer)
                                  .SelectMany(x => (x as IEdmEntityContainer).EntitySets())
                                  .BestMatch(x => x.EntityType().Name, linkType.Name, _session.Pluralizer);
                    var formattedKey = _session.Adapter.ConvertKeyValuesToUriLiteral(
                        linkKey.ToDictionary(x => x.Name, x => linkEntry[x.Name]), true);
                    linkUri = linkSet.Name + formattedKey;
                }
                var link = new ODataEntityReferenceLink
                {
                    Url = Utils.CreateAbsoluteUri(_session.Settings.UrlBase, linkUri)
                };

                await entryWriter.WriteEntityReferenceLinkAsync(link);
            }

            await entryWriter.WriteEndAsync();
        }
        private Microsoft.OData.Core.ODataEntry CreateODataEntry(string typeName, IDictionary <string, object> properties)
        {
            var entry = new Microsoft.OData.Core.ODataEntry()
            {
                TypeName = typeName
            };

            var typeProperties = (_model.FindDeclaredType(entry.TypeName) as IEdmEntityType).Properties();
            Func <string, string> findMatchingPropertyName = name =>
            {
                var property = typeProperties.BestMatch(y => y.Name, name, _session.Pluralizer);
                return(property != null ? property.Name : name);
            };

            entry.Properties = properties.Select(x => new ODataProperty()
            {
                Name  = findMatchingPropertyName(x.Key),
                Value = GetPropertyValue(typeProperties, x.Key, x.Value)
            }).ToList();

            return(entry);
        }