diff --git a/src/Microsoft.AspNetCore.OData/Formatter/Deserialization/ODataResourceDeserializer.cs b/src/Microsoft.AspNetCore.OData/Formatter/Deserialization/ODataResourceDeserializer.cs
index 4fdc92d2b..c0e6ece3f 100644
--- a/src/Microsoft.AspNetCore.OData/Formatter/Deserialization/ODataResourceDeserializer.cs
+++ b/src/Microsoft.AspNetCore.OData/Formatter/Deserialization/ODataResourceDeserializer.cs
@@ -474,6 +474,21 @@ public virtual void ApplyNestedProperty(object resource, ODataNestedResourceInfo
}
}
+ ///
+ /// Deserializes the nested property info from into .
+ /// Nested property info contains annotations for the property but without the property value.
+ ///
+ /// The object into which the properties should be read.
+ /// The resource object containing the structural properties.
+ /// The type of the resource.
+ /// The deserializer context.
+ public virtual void ApplyNestedPropertyInfos(object resource, ODataResourceWrapper resourceWrapper,
+ IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
+ {
+ // Add this method to provide customers an solution to customize the deserializer to handle the properties without value.
+ // We Will fill this method later when we enable the instance annotation feature.
+ }
+
///
/// Deserializes the structural properties from into .
///
@@ -489,7 +504,7 @@ public virtual void ApplyStructuralProperties(object resource, ODataResourceWrap
throw new ArgumentNullException(nameof(resourceWrapper));
}
- foreach (ODataProperty property in resourceWrapper.Resource.Properties)
+ foreach (ODataProperty property in resourceWrapper.Resource.Properties.OfType())
{
ApplyStructuralProperty(resource, property, structuredType, readContext);
}
@@ -532,6 +547,7 @@ private void ApplyResourceProperties(object resource, ODataResourceWrapper resou
IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
{
ApplyStructuralProperties(resource, resourceWrapper, structuredType, readContext);
+ ApplyNestedPropertyInfos(resource, resourceWrapper, structuredType, readContext);
ApplyNestedProperties(resource, resourceWrapper, structuredType, readContext);
}
diff --git a/src/Microsoft.AspNetCore.OData/Formatter/Wrapper/ODataReaderExtensions.cs b/src/Microsoft.AspNetCore.OData/Formatter/Wrapper/ODataReaderExtensions.cs
index c0fc09238..f71e2116d 100644
--- a/src/Microsoft.AspNetCore.OData/Formatter/Wrapper/ODataReaderExtensions.cs
+++ b/src/Microsoft.AspNetCore.OData/Formatter/Wrapper/ODataReaderExtensions.cs
@@ -200,6 +200,12 @@ private static void ReadODataItem(ODataReader reader, Stack it
resourceSetParentWrapper.Items.Add(new ODataPrimitiveWrapper((ODataPrimitiveValue)reader.Item));
break;
+ case ODataReaderState.NestedProperty:
+ Contract.Assert(itemsStack.Count > 0, "The nested property info should be a non-null primitive value within resource wrapper.");
+ ODataResourceWrapper resourceParentWrapper = (ODataResourceWrapper)itemsStack.Peek();
+ resourceParentWrapper.NestedPropertyInfos.Add((ODataPropertyInfo)reader.Item);
+ break;
+
default:
Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state.");
break;
diff --git a/src/Microsoft.AspNetCore.OData/Formatter/Wrapper/ODataResourceWrapper.cs b/src/Microsoft.AspNetCore.OData/Formatter/Wrapper/ODataResourceWrapper.cs
index a0dc68b37..36f39e887 100644
--- a/src/Microsoft.AspNetCore.OData/Formatter/Wrapper/ODataResourceWrapper.cs
+++ b/src/Microsoft.AspNetCore.OData/Formatter/Wrapper/ODataResourceWrapper.cs
@@ -26,6 +26,8 @@ public ODataResourceWrapper(ODataResourceBase resource)
IsDeletedResource = resource != null && resource is ODataDeletedResource;
NestedResourceInfos = new List();
+
+ NestedPropertyInfos = new List();
}
///
@@ -42,5 +44,11 @@ public ODataResourceWrapper(ODataResourceBase resource)
/// Gets the inner nested resource infos.
///
public IList NestedResourceInfos { get; }
+
+ ///
+ /// Gets the nested property infos.
+ /// The nested property info is a property without value but could have instance annotations.
+ ///
+ public IList NestedPropertyInfos { get; }
}
}
diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
index 24b0986a1..1d2c48fb2 100644
--- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
+++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
@@ -3606,6 +3606,16 @@
The type of the resource.
The deserializer context.
+
+
+ Deserializes the nested property info from into .
+ Nested property info contains annotations for the property but without the property value.
+
+ The object into which the properties should be read.
+ The resource object containing the structural properties.
+ The type of the resource.
+ The deserializer context.
+
Deserializes the structural properties from into .
@@ -6331,6 +6341,12 @@
Gets the inner nested resource infos.
+
+
+ Gets the nested property infos.
+ The nested property info is a property without value but could have instance annotations.
+
+
Provides extension methods for to add OData routes.
@@ -8668,7 +8684,7 @@
- Get the ODaya query context.
+ Get the OData query context.
The response value.
The content as SingleResult.Queryable.
diff --git a/src/Microsoft.AspNetCore.OData/PublicAPI.Shipped.txt b/src/Microsoft.AspNetCore.OData/PublicAPI.Shipped.txt
index 1874ae4d2..bdeae4932 100644
--- a/src/Microsoft.AspNetCore.OData/PublicAPI.Shipped.txt
+++ b/src/Microsoft.AspNetCore.OData/PublicAPI.Shipped.txt
@@ -656,6 +656,7 @@ Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceSetWrapper.ResourceSet
Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper
Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper.IsDeletedResource.get -> bool
Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper.NestedResourceInfos.get -> System.Collections.Generic.IList
+Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper.NestedPropertyInfos.get -> System.Collections.Generic.IList
Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper.ODataResourceWrapper(Microsoft.OData.ODataResourceBase resource) -> void
Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper.Resource.get -> Microsoft.OData.ODataResourceBase
Microsoft.AspNetCore.OData.ODataApplicationBuilderExtensions
@@ -1817,6 +1818,7 @@ virtual Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataPrimitiveDeser
virtual Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataResourceDeserializer.ApplyDeletedResource(object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) -> void
virtual Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataResourceDeserializer.ApplyNestedProperties(object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) -> void
virtual Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataResourceDeserializer.ApplyNestedProperty(object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataNestedResourceInfoWrapper resourceInfoWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) -> void
+virtual Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataResourceDeserializer.ApplyNestedPropertyInfos(object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) -> void
virtual Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataResourceDeserializer.ApplyStructuralProperties(object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) -> void
virtual Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataResourceDeserializer.ApplyStructuralProperty(object resource, Microsoft.OData.ODataProperty structuralProperty, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) -> void
virtual Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataResourceDeserializer.CreateResourceInstance(Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) -> object
diff --git a/test/Microsoft.AspNetCore.OData.Tests/Formatter/Deserialization/ODataResourceDeserializerTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Formatter/Deserialization/ODataResourceDeserializerTests.cs
index 00fbe5d0d..7e76115a7 100644
--- a/test/Microsoft.AspNetCore.OData.Tests/Formatter/Deserialization/ODataResourceDeserializerTests.cs
+++ b/test/Microsoft.AspNetCore.OData.Tests/Formatter/Deserialization/ODataResourceDeserializerTests.cs
@@ -418,6 +418,23 @@ public void ReadResource_Calls_ApplyStructuralProperties()
deserializer.Verify();
}
+ [Fact]
+ public void ReadResource_Calls_ApplyNestedPropertyInfos()
+ {
+ // Arrange
+ Mock deserializer = new Mock(_deserializerProvider);
+ ODataResourceWrapper resourceWrapper = new ODataResourceWrapper(new ODataResource { Properties = Enumerable.Empty() });
+ deserializer.CallBase = true;
+ deserializer.Setup(d => d.CreateResourceInstance(_productEdmType, _readContext)).Returns(42);
+ deserializer.Setup(d => d.ApplyNestedPropertyInfos(42, resourceWrapper, _productEdmType, _readContext)).Verifiable();
+
+ // Act
+ deserializer.Object.ReadResource(resourceWrapper, _productEdmType, _readContext);
+
+ // Assert
+ deserializer.Verify();
+ }
+
[Fact]
public void ReadResource_Calls_ApplyNestedProperties()
{
diff --git a/test/Microsoft.AspNetCore.OData.Tests/Formatter/Wrapper/ODataReaderExtensionsTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Formatter/Wrapper/ODataReaderExtensionsTests.cs
index 492093e7b..743ad7ca0 100644
--- a/test/Microsoft.AspNetCore.OData.Tests/Formatter/Wrapper/ODataReaderExtensionsTests.cs
+++ b/test/Microsoft.AspNetCore.OData.Tests/Formatter/Wrapper/ODataReaderExtensionsTests.cs
@@ -26,6 +26,13 @@ static ODataReaderExtensionsTests()
{
Model = new EdmModel();
+ // Enum type simpleEnum
+ EdmEnumType colorEnum = new EdmEnumType("NS", "Color");
+ colorEnum.AddMember(new EdmEnumMember(colorEnum, "Red", new EdmEnumMemberValue(0)));
+ colorEnum.AddMember(new EdmEnumMember(colorEnum, "Blue", new EdmEnumMemberValue(1)));
+ colorEnum.AddMember(new EdmEnumMember(colorEnum, "Yellow", new EdmEnumMemberValue(2)));
+ Model.AddElement(colorEnum);
+
// Address
EdmComplexType address = new EdmComplexType("NS", "Address");
address.AddStructuralProperty("Street", EdmCoreModel.Instance.GetString(false));
@@ -36,6 +43,7 @@ static ODataReaderExtensionsTests()
Model.AddElement(customer);
customer.AddKeys(customer.AddStructuralProperty("CustomerID", EdmCoreModel.Instance.GetInt32(false)));
customer.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(true));
+ customer.AddStructuralProperty("Color", new EdmEnumTypeReference(colorEnum, true));
customer.AddStructuralProperty("Location", new EdmComplexTypeReference(address, false));
// Order
@@ -116,6 +124,115 @@ public async Task ReadResourceWorksAsExpected()
Assert.Equal(new[] { "Location", "Order", "Orders" }, resource.NestedResourceInfos.Select(n => n.NestedResourceInfo.Name));
}
+ [Fact]
+ public async Task ReadResourceWithPropertyWithoutValueButWithInstanceAnnotationsWorksAsExpected()
+ {
+ // Arrange
+ // Property 'Name' without value but with instance annotations
+ const string payload =
+ "{" +
+ "\"@odata.context\":\"http://localhost/$metadata#Customers/$entity\"," +
+ "\"CustomerID\": 17," +
+ "\"Name@Custom.PrimitiveAnnotation\":123," +
+ "\"Name@Custom.BooleanAnnotation\":true," +
+ "\"Location\": { \"Street\":\"154TH AVE\"}" +
+ "}";
+
+ IEdmEntitySet customers = Model.EntityContainer.FindEntitySet("Customers");
+ Assert.NotNull(customers); // Guard
+
+ // Act
+ Func> func = mr => mr.CreateODataResourceReaderAsync(customers, customers.EntityType);
+ ODataItemWrapper item = await ReadPayloadAsync(payload, Model, func, ODataVersion.V4, false, "*");
+
+ // Assert
+ Assert.NotNull(item);
+ ODataResourceWrapper resource = Assert.IsType(item);
+ Assert.NotNull(resource.Resource);
+
+ // Be noted, the ODL 8 inserts the primitive properties without value into the 'Properties' also.
+ // So, the Resource.Properties contains "CustomerID" and "Name".
+ Assert.Equal(2, resource.Resource.Properties.Count());
+
+ ODataPropertyInfo customerIdPropInfo = resource.Resource.Properties.First(c => c.Name == "CustomerID");
+ ODataProperty customerIdProp = Assert.IsType(customerIdPropInfo);
+ Assert.Equal("CustomerID", customerIdProp.Name);
+ Assert.Equal(17, customerIdProp.Value);
+
+ ODataPropertyInfo namePropInfo = resource.Resource.Properties.First(c => c.Name == "Name");
+ Assert.IsNotType(namePropInfo);
+ Assert.Equal(2, namePropInfo.InstanceAnnotations.Count);
+
+ ODataPropertyInfo nameProp = Assert.Single(resource.NestedPropertyInfos);
+ Assert.Equal("Name", nameProp.Name);
+ Assert.Equal(2, nameProp.InstanceAnnotations.Count);
+
+ ODataInstanceAnnotation primitiveAnnotation = nameProp.InstanceAnnotations.First(i => i.Name == "Custom.PrimitiveAnnotation");
+ ODataPrimitiveValue primitiveValue = Assert.IsType(primitiveAnnotation.Value);
+ Assert.Equal(123, primitiveValue.Value);
+
+ ODataInstanceAnnotation booleanAnnotation = nameProp.InstanceAnnotations.First(i => i.Name == "Custom.BooleanAnnotation");
+ ODataPrimitiveValue booleanValue = Assert.IsType(booleanAnnotation.Value);
+ Assert.True((bool)booleanValue.Value);
+
+ ODataNestedResourceInfoWrapper nestedInfoWrapper = Assert.Single(resource.NestedResourceInfos);
+ Assert.Equal("Location", nestedInfoWrapper.NestedResourceInfo.Name);
+ }
+
+ [Fact]
+ public async Task ReadResourceWithNonPrimitivePropertyWithoutValueButWithInstanceAnnotationsWorksAsExpected()
+ {
+ // Arrange
+ const string payload =
+ "{" +
+ "\"@odata.context\":\"http://localhost/$metadata#Customers/$entity\"," +
+ "\"Color@Custom.PrimitiveAnnotation\":42," +
+ "\"Name@Custom.PrimitiveAnnotation\":123," + // Put 'Name' after 'Color' property is by design
+ "\"Location@Custom.PrimitiveAnnotation\":9" +
+ "}";
+
+ IEdmEntitySet customers = Model.EntityContainer.FindEntitySet("Customers");
+ Assert.NotNull(customers); // Guard
+
+ // Act
+ Func> func = mr => mr.CreateODataResourceReaderAsync(customers, customers.EntityType);
+ ODataItemWrapper item = await ReadPayloadAsync(payload, Model, func, ODataVersion.V4, false, "*");
+
+ // Assert
+ Assert.NotNull(item);
+ ODataResourceWrapper resource = Assert.IsType(item);
+ Assert.NotNull(resource.Resource);
+
+ ODataPropertyInfo namePropInfo = Assert.Single(resource.Resource.Properties);
+ Assert.IsNotType(namePropInfo);
+ Assert.Single(namePropInfo.InstanceAnnotations);
+
+ Assert.Equal(3, resource.NestedPropertyInfos.Count);
+
+ // -- Color
+ ODataPropertyInfo colorProp = resource.NestedPropertyInfos.Single(c => c.Name == "Color");
+ ODataInstanceAnnotation colorAnnotation = Assert.Single(colorProp.InstanceAnnotations);
+ Assert.Equal("Custom.PrimitiveAnnotation", colorAnnotation.Name);
+ ODataPrimitiveValue primitiveValue = Assert.IsType(colorAnnotation.Value);
+ Assert.Equal(42, primitiveValue.Value);
+
+ // -- Name
+ ODataPropertyInfo nameProp = resource.NestedPropertyInfos.Single(c => c.Name == "Name");
+ ODataInstanceAnnotation primitiveAnnotation = Assert.Single(nameProp.InstanceAnnotations);
+ Assert.Equal("Custom.PrimitiveAnnotation", primitiveAnnotation.Name);
+ primitiveValue = Assert.IsType(primitiveAnnotation.Value);
+ Assert.Equal(123, primitiveValue.Value);
+
+ // -- Location
+ ODataPropertyInfo locationProp = resource.NestedPropertyInfos.Single(c => c.Name == "Location");
+ ODataInstanceAnnotation locationAnnotation = Assert.Single(locationProp.InstanceAnnotations);
+ Assert.Equal("Custom.PrimitiveAnnotation", locationAnnotation.Name);
+ primitiveValue = Assert.IsType(locationAnnotation.Value);
+ Assert.Equal(9, primitiveValue.Value);
+
+ Assert.Empty(resource.NestedResourceInfos);
+ }
+
[Fact]
public async Task ReadResourceSetWorksAsExpected()
{
@@ -575,7 +692,8 @@ public async Task ReadEntityReferenceLinksSetWorksAsExpected_V401()
private async Task ReadPayloadAsync(string payload,
IEdmModel edmModel, Func> createReader, ODataVersion version = ODataVersion.V4,
- bool readUntypedAsString = false)
+ bool readUntypedAsString = false,
+ string annotationFilter = null)
{
var message = new InMemoryMessage()
{
@@ -591,6 +709,11 @@ private async Task ReadPayloadAsync(string payload,
Version = version,
};
+ if (annotationFilter != null)
+ {
+ readerSettings.ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter(annotationFilter);
+ }
+
using (var msgReader = new ODataMessageReader((IODataRequestMessageAsync)message, readerSettings, edmModel))
{
ODataReader reader = await createReader(msgReader);
diff --git a/test/Microsoft.AspNetCore.OData.Tests/Formatter/Wrapper/ODataResourceWrapperTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Formatter/Wrapper/ODataResourceWrapperTests.cs
new file mode 100644
index 000000000..d6ad38778
--- /dev/null
+++ b/test/Microsoft.AspNetCore.OData.Tests/Formatter/Wrapper/ODataResourceWrapperTests.cs
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) .NET Foundation and Contributors. All rights reserved.
+// See License.txt in the project root for license information.
+//
+//------------------------------------------------------------------------------
+
+using Microsoft.AspNetCore.OData.Formatter.Wrapper;
+using Microsoft.OData;
+using Xunit;
+
+namespace Microsoft.AspNetCore.OData.Tests.Formatter.Wrapper
+{
+ public class ODataResourceWrapperTests
+ {
+ [Fact]
+ public void ODataResourceWrapper_SetsUsingODataResource_CorrectProperties()
+ {
+ // Arrange & Act & Assert
+ ODataResource resource = new ODataResource
+ {
+ TypeName = "NS.Namespace"
+ };
+
+ // Act
+ ODataResourceWrapper resourceWrapper = new ODataResourceWrapper(resource);
+
+ // Assert
+ Assert.Same(resource, resourceWrapper.Resource);
+ Assert.False(resourceWrapper.IsDeletedResource);
+ Assert.Empty(resourceWrapper.NestedPropertyInfos);
+ Assert.Empty(resourceWrapper.NestedResourceInfos);
+ }
+
+ [Fact]
+ public void ODataResourceWrapper_SetsUsingODataDeletedResource_CorrectProperties()
+ {
+ // Arrange & Act & Assert
+ ODataDeletedResource deletedResource = new ODataDeletedResource
+ {
+ TypeName = "NS.Namespace"
+ };
+
+ // Act
+ ODataResourceWrapper resourceWrapper = new ODataResourceWrapper(deletedResource);
+
+ // Assert
+ Assert.Same(deletedResource, resourceWrapper.Resource);
+ Assert.True(resourceWrapper.IsDeletedResource);
+ Assert.Empty(resourceWrapper.NestedPropertyInfos);
+ Assert.Empty(resourceWrapper.NestedResourceInfos);
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net8.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net8.bsl
index 0cf9bca97..e4e9b3438 100644
--- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net8.bsl
+++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net8.bsl
@@ -2018,6 +2018,7 @@ public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataResourceD
public virtual void ApplyDeletedResource (object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext)
public virtual void ApplyNestedProperties (object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext)
public virtual void ApplyNestedProperty (object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataNestedResourceInfoWrapper resourceInfoWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext)
+ public virtual void ApplyNestedPropertyInfos (object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext)
public virtual void ApplyStructuralProperties (object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext)
public virtual void ApplyStructuralProperty (object resource, Microsoft.OData.ODataProperty structuralProperty, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext)
public virtual object CreateResourceInstance (Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext)
@@ -2716,6 +2717,7 @@ public sealed class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWr
public ODataResourceWrapper (Microsoft.OData.ODataResourceBase resource)
bool IsDeletedResource { public get; }
+ System.Collections.Generic.IList`1[[Microsoft.OData.ODataPropertyInfo]] NestedPropertyInfos { public get; }
System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataNestedResourceInfoWrapper]] NestedResourceInfos { public get; }
Microsoft.OData.ODataResourceBase Resource { public get; }
}