/// <summary> /// Creates the <see cref="ODataEntry"/> to be written while writing this entity. /// </summary> /// <param name="selectExpandNode">The <see cref="SelectExpandNode"/> describing the response graph.</param> /// <param name="entityInstanceContext">The context for the entity instance being written.</param> /// <returns>The created <see cref="ODataEntry"/>.</returns> public virtual ODataEntry CreateEntry(SelectExpandNode selectExpandNode, EntityInstanceContext entityInstanceContext) { if (selectExpandNode == null) { throw Error.ArgumentNull("selectExpandNode"); } if (entityInstanceContext == null) { throw Error.ArgumentNull("entityInstanceContext"); } string typeName = entityInstanceContext.EntityType.FullName(); ODataEntry entry = new ODataEntry { TypeName = typeName, Properties = CreateStructuralPropertyBag(selectExpandNode.SelectedStructuralProperties, entityInstanceContext), }; // Try to add the dynamic properties if the entity type is open. if ((entityInstanceContext.EntityType.IsOpen && selectExpandNode.SelectAllDynamicProperties) || (entityInstanceContext.EntityType.IsOpen && selectExpandNode.SelectedDynamicProperties.Any())) { IEdmTypeReference entityTypeReference = entityInstanceContext.EntityType.ToEdmTypeReference(isNullable: false); List<ODataProperty> dynamicProperties = AppendDynamicProperties(entityInstanceContext.EdmObject, (IEdmStructuredTypeReference)entityTypeReference, entityInstanceContext.SerializerContext, entry.Properties.ToList(), selectExpandNode.SelectedDynamicProperties.ToArray()); if (dynamicProperties != null) { entry.Properties = entry.Properties.Concat(dynamicProperties); } } IEnumerable<ODataAction> actions = CreateODataActions(selectExpandNode.SelectedActions, entityInstanceContext); foreach (ODataAction action in actions) { entry.AddAction(action); } IEnumerable<ODataFunction> functions = CreateODataFunctions(selectExpandNode.SelectedFunctions, entityInstanceContext); foreach (ODataFunction function in functions) { entry.AddFunction(function); } IEdmEntityType pathType = GetODataPathType(entityInstanceContext.SerializerContext); AddTypeNameAnnotationAsNeeded(entry, pathType, entityInstanceContext.SerializerContext.MetadataLevel); if (entityInstanceContext.NavigationSource != null) { if (!(entityInstanceContext.NavigationSource is IEdmContainedEntitySet)) { IEdmModel model = entityInstanceContext.SerializerContext.Model; NavigationSourceLinkBuilderAnnotation linkBuilder = model.GetNavigationSourceLinkBuilder(entityInstanceContext.NavigationSource); EntitySelfLinks selfLinks = linkBuilder.BuildEntitySelfLinks(entityInstanceContext, entityInstanceContext.SerializerContext.MetadataLevel); if (selfLinks.IdLink != null) { entry.Id = selfLinks.IdLink; } if (selfLinks.ReadLink != null) { entry.ReadLink = selfLinks.ReadLink; } if (selfLinks.EditLink != null) { entry.EditLink = selfLinks.EditLink; } } string etag = CreateETag(entityInstanceContext); if (etag != null) { entry.ETag = etag; } } return entry; }
public void InjectMetadataBuilderShouldNotSetBuilderOnEntryFunctions() { var entry = new ODataEntry(); var builder = new TestEntityMetadataBuilder(entry); var function1 = new ODataFunction { Metadata = new Uri("http://service/$metadata#function1", UriKind.Absolute) }; var function2 = new ODataFunction { Metadata = new Uri("http://service/$metadata#function2", UriKind.Absolute) }; entry.AddFunction(function1); entry.AddFunction(function2); testSubject.InjectMetadataBuilder(entry, builder); function1.GetMetadataBuilder().Should().BeNull(); function2.GetMetadataBuilder().Should().BeNull(); }
public void InjectMetadataBuilderShouldSetBuilderOnEntryFunctions() { var entry = new ODataEntry(); var builder = new TestEntityMetadataBuilder(entry); var function1 = new ODataFunction { Metadata = new Uri(MetadataDocumentUri, "#function1") }; var function2 = new ODataFunction { Metadata = new Uri(MetadataDocumentUri, "#function2") }; entry.AddFunction(function1); entry.AddFunction(function2); testSubject.InjectMetadataBuilder(entry, builder); function1.GetMetadataBuilder().Should().BeSameAs(builder); function2.GetMetadataBuilder().Should().BeSameAs(builder); }
public void ShouldWriteFunctionForRequestEntryPayloadWithUserModel() { ODataEntry entry = new ODataEntry { TypeName = "NS.MyDerivedEntityType" }; entry.AddFunction(new ODataFunction {Metadata = new Uri("#Function1", UriKind.Relative)}); const string expectedPayload = "{\"@odata.type\":\"#NS.MyDerivedEntityType\",\"#Function1\":{}}"; Action action = () => this.WriteNestedItemsAndValidatePayload(entitySet: null, entityType: null, nestedItemToWrite: new[] { entry }, expectedPayload: expectedPayload, writingResponse: false); action.ShouldThrow<ODataException>().WithMessage(Strings.WriterValidationUtils_OperationInRequest("#Function1")); }
public void ShouldWriteFunctionForResponseEntryPayloadWithUserModel() { ODataEntry entry = new ODataEntry { TypeName = "NS.MyDerivedEntityType" }; entry.AddFunction(new ODataFunction { Metadata = new Uri("#Function1", UriKind.Relative) }); const string expectedPayload = "{\"@odata.context\":\"http://odata.org/test/$metadata#MySet/$entity\",\"@odata.type\":\"#NS.MyDerivedEntityType\",\"#Function1\":{}}"; this.WriteNestedItemsAndValidatePayload(entitySet: this.entitySet, entityType: null, nestedItemToWrite: new[] { entry }, expectedPayload: expectedPayload, writingResponse: true); }
public void ActionAndFunctionPayloadOrderTest() { EdmModel model = new EdmModel(); var container = new EdmEntityContainer("TestModel", "TestContainer"); model.AddElement(container); var otherType = new EdmEntityType("TestModel", "OtherType"); otherType.AddKeys(otherType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false))); model.AddElement(otherType); container.AddEntitySet("OtherType", otherType); var nonMLEBaseType = new EdmEntityType("TestModel", "NonMLEBaseType"); nonMLEBaseType.AddKeys(nonMLEBaseType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false))); model.AddElement(nonMLEBaseType); var nonMLESet = container.AddEntitySet("NonMLESet", nonMLEBaseType); var nonMLEType = new EdmEntityType("TestModel", "NonMLEType", nonMLEBaseType); nonMLEType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(true)); nonMLEType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "NavProp", Target = otherType, TargetMultiplicity = EdmMultiplicity.Many }); model.AddElement(nonMLEType); container.AddEntitySet("NonMLEType", nonMLEType); ODataAction action = new ODataAction { Metadata = new Uri("http://odata.org/test/$metadata#defaultAction"), Title = "Default Action", Target = new Uri("http://www.odata.org/defaultAction"), }; ODataFunction function = new ODataFunction { Metadata = new Uri("http://odata.org/test/$metadata#defaultFunction()"), Title = "Default Function", Target = new Uri("defaultFunctionTarget", UriKind.Relative) }; string defaultJson = string.Join("$(NL)", "{{", "{1}" + "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"#TestModel.NonMLEType\"{0},\"#defaultAction\":{{", "\"title\":\"Default Action\",\"target\":\"http://www.odata.org/defaultAction\"", "}},\"#defaultFunction()\":{{", "\"title\":\"Default Function\",\"target\":\"defaultFunctionTarget\"", "}}", "}}"); var entryWithActionAndFunction = new ODataEntry() { TypeName = "TestModel.NonMLEType", }; entryWithActionAndFunction.AddAction(action); entryWithActionAndFunction.AddFunction(function); IEnumerable<EntryPayloadTestCase> testCases = new[] { new EntryPayloadTestCase { DebugDescription = "Functions and actions available at the beginning.", Entry = entryWithActionAndFunction, Model = model, EntitySet = nonMLESet, Json = defaultJson }, }; IEnumerable<PayloadWriterTestDescriptor<ODataItem>> testDescriptors = testCases.Select(testCase => new PayloadWriterTestDescriptor<ODataItem>( this.Settings, new ODataItem[] { testCase.Entry }, tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Json = string.Format(CultureInfo.InvariantCulture, testCase.Json, string.Empty, tc.IsRequest ? string.Empty : (JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ",")), FragmentExtractor = (result) => result.RemoveAllAnnotations(true) }) { DebugDescription = testCase.DebugDescription, Model = testCase.Model, PayloadEdmElementContainer = testCase.EntitySet, PayloadEdmElementType = testCase.EntityType, SkipTestConfiguration = testCase.SkipTestConfiguration }); testDescriptors = testDescriptors.Concat(testCases.Select(testCase => new PayloadWriterTestDescriptor<ODataItem>( this.Settings, new ODataItem[] { testCase.Entry, new ODataNavigationLink { Name = "NavProp", IsCollection = true, Url = new Uri("http://odata.org/navprop/uri") }}, tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Json = string.Format(CultureInfo.InvariantCulture, testCase.Json, tc.IsRequest ? ",\"NavProp\":[$(NL){$(NL)\"__metadata\":{$(NL)\"uri\":\"http://odata.org/navprop/uri\"$(NL)}$(NL)}$(NL)]" : ",\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navprop/uri\"", tc.IsRequest ? string.Empty : (JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ",")), FragmentExtractor = (result) => result.RemoveAllAnnotations(true) }) { DebugDescription = testCase.DebugDescription + "- with navigation property", Model = testCase.Model, PayloadEdmElementContainer = testCase.EntitySet, PayloadEdmElementType = testCase.EntityType, SkipTestConfiguration = testCase.SkipTestConfiguration })); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, // Actions/functions are only supported in responses. this.WriterTestConfigurationProvider.JsonLightFormatConfigurationsWithIndent.Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { TestWriterUtils.WriteAndVerifyODataEdmPayload(testDescriptor.DeferredLinksToEntityReferenceLinksInRequest(testConfiguration), testConfiguration, this.Assert, this.Logger); }); }
public void NoOpMetadataBuilderShouldReturnFunctionsSetByUser() { ODataFunction function = new ODataFunction() { Metadata = new Uri("http://example.com/$metadata#Function"), Target = new Uri("http://example.com/Function"), Title = "FunctionTitle" }; ODataEntry entry = new ODataEntry(); entry.AddFunction(function); new NoOpEntityMetadataBuilder(entry).GetFunctions() .Should().ContainSingle(f => f == function); // Verify that the Function information wasn't removed or changed. function.Metadata.Should().Be(new Uri("http://example.com/$metadata#Function")); function.Target.Should().Be(new Uri("http://example.com/Function")); function.Title.Should().Be("FunctionTitle"); }