Skip to content

Dynamic complex resource not serialized if instance is derived #53

@gathogojr

Description

@gathogojr

Assemblies affected

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

Bug description/Reproduce steps
Consider a contrived OData service where:

  • Order is an entity type
  • Address is an open complex type
  • VipAddress is a complex type that derives from Address complex type
  • City is a complex type
  • ShippingAddress is a complex property of type Address defined on Order entity entity

If the ShippingAddress property is initialized to an instance of VipAddress, and a dynamic property of type City added to the dynamic properties dictionary as demonstrated in the code below, the dynamic complex resource is not serialized in the response:

public class OrdersController : ODataController
{
    private static readonly List<Order> _orders = new()
    {
        new Order
        {
            Id = 1,
            ShippingAddress = new VipAddress
            {
                Street = "123 Main St",
                PostalCode = "12345",
                DynamicProperties = new Dictionary<string, object>
                {
                    { "City", new City { Name = "Springfield" } }
                }
            }
        }
    };

    public ActionResult<Order> Get(int key)
    {
        var order = _orders.FirstOrDefault(o => o.Id == key);
        if (order == null)
        {
            return NotFound();
        }

        return Ok(order);
    }
}

Data Model

namespace Ex341.Models
{
    public class Order
    {
        public int Id { get; set; }
        public Address? ShippingAddress { get; set; }
    }

    public class Address
    {
        public string Street { get; set; } = null!;
        public Dictionary<string, object>? DynamicProperties { get; set; }
    }

    public class VipAddress : Address
    {
        public string? PostalCode { get; set; }
    }

    public class City
    {
        public string Name { get; set; } = null!;
    }
}

EDM (CSDL) Model

<?xml version="1.0" encoding="UTF-8"?>
<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="Ex341.Models">
      <EntityType Name="Order">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.Int32" Nullable="false" />
        <Property Name="ShippingAddress" Type="Ex341.Models.Address" />
      </EntityType>
      <ComplexType Name="Address" OpenType="true">
        <Property Name="Street" Type="Edm.String" Nullable="false" />
      </ComplexType>
      <ComplexType Name="VipAddress" BaseType="Ex341.Models.Address">
        <Property Name="PostalCode" Type="Edm.String" />
      </ComplexType>
      <ComplexType Name="City">
        <Property Name="Name" Type="Edm.String" Nullable="false" />
      </ComplexType>
    </Schema>
    <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Default">
      <EntityContainer Name="Container">
        <EntitySet Name="Orders" EntityType="Ex341.Models.Order" />
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

Request/Response
Request:

GET http://localhost:5087/Orders(1)

Response:

{
  "@odata.context": "http://localhost:5087/$metadata#Orders/$entity",
  "Id": 1,
  "ShippingAddress": {
    "@odata.type": "#Ex341.Models.VipAddress",
    "Street": "123 Main St",
    "PostalCode": "12345"
  }
}

Expected behavior
I would expect the dynamic complex resource City to be serialized in the response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions