AspNetCoreOData icon indicating copy to clipboard operation
AspNetCoreOData copied to clipboard

Dynamic single-valued complex properties are not serialized in a delta response payload

Open gathogojr opened this issue 9 months ago • 0 comments

Assemblies affected

  • ASP.NET Core OData 8.x
  • ASP.NET Core OData 9.x

Describe the bug Related to https://github.com/OData/AspNetCoreOData/issues/1425. After #1425 is mitigated, dynamic single-valued complex properties are not serialized in a delta response payload.

Reproduce steps Consider a simple OData service that processes a delta payload comprising of the following:

Data model:

namespace SampleNs.Models
{
    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Dictionary<string, object> DynamicProperties { get; set; }
    }

    public class Address
    {
        public string City { get; set; }
    }
}

Controller:

namespace SampleNs.Controllers
{
    public class CustomersController : ODataController
    {
        public ActionResult PatchAsync([FromBody] DeltaSet<Customer> deltaSet)
        {
            return Ok(deltaSet);
        }
    }
}

Service Configuration:

var builder = WebApplication.CreateBuilder(args);

var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.ComplexType<Address>();
modelBuilder.EntitySet<Customer>("Customers");

builder.Services.AddControllers().AddOData(
    options => options.EnableQueryFeatures().AddRouteComponents(
        modelBuilder.GetEdmModel()));

var app = builder.Build();

app.UseRouting();
app.MapControllers();

app.Run();

EDM (CSDL) Model

<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
    <edmx:DataServices>
        <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="SampleNs.Models">
            <ComplexType Name="Address">
                <Property Name="City" Type="Edm.String" Nullable="false"/>
            </ComplexType>
            <EntityType Name="Customer" OpenType="true">
                <Key>
                    <PropertyRef Name="Id"/>
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false"/>
                <Property Name="Name" Type="Edm.String" Nullable="false"/>
            </EntityType>
        </Schema>
        <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Default">
            <EntityContainer Name="Container">
                <EntitySet Name="Customers" EntityType="SampleNs.Models.Customer"/>
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

Request/Response Uri:

GET http://localhost:5013/Customers

Request:

{
  "@odata.context": "http://localhost:5013/$metadata#Customers/$delta",
  "value": [
    {
      "Id": 1,
      "RetailAddress": {
	"@odata.type": "#SampleNs.Models.Address",
        "City": "Seattle"
      }
    }
  ]
}

Response:

{
  "@odata.context": "http://localhost:5013/$metadata#Customers/$delta",
  "value": [
    {
      "Id": 1
    }
  ]
}

Expected behavior The following response should be returned:

{
  "@odata.context": "http://localhost:5013/$metadata#Customers/$delta",
  "value": [
    {
      "Id": 1,
      "RetailAddress": {
	"@odata.type": "#SampleNs.Models.Address",
        "City": "Seattle"
      }
    }
  ]
}

Screenshots Dynamic single-valued complex property is deserialized as expected:

Image

Additional context A dynamic collection-valued complex property is also not serialized in a delta response. This is a bug. NOTE: A dynamic collection-valued complex property should not be represented as a DeltaSet<{Complex Type}> in a typed delta. The challenge with that in respect to patching would be in determining which item in the delta set corresponds to which item in the complex property collection since complex objects have no IDs. We can/should confirm this behaviour. cc @mikepizzo - Confirmed as the right behaviour We should confirm if dynamic primitive properties are serialized in a delta response - Chances are high that they're not

gathogojr avatar Feb 25 '25 09:02 gathogojr