AspNetCoreOData
AspNetCoreOData copied to clipboard
Dynamically fetching property of a singleton entity in odata 8.0.11
Assemblies affected ASP.NET Core OData 8.0.11
Describe the bug When trying to fetch property of a singleton object, it fails with a 404. Is it possible to implement a single controller method which could fetch any property of a singleton/entity using reflection?
Reproduce steps
Program.cs
builder.Services.AddControllers()
.AddOData(opt =>
{
var builder = new ODataConventionModelBuilder
{
Namespace = "MyOdataApp",
ContainerName = "ODataAppContainer",
};
opt.EnableQueryFeatures();
builder.Singleton<Warehouse>("warehouse");
opt.AddRouteComponents("v1.0", builder.GetEdmModel());
});
Controller
[Route("v1.0/warehouse")]
[ApiController]
public class WarehouseController : ODataController
{
private readonly Warehouse warehouse = new Warehouse
{
Id = "w1",
Name = "MyWarehouse",
Products = new List<Product>
{
new Product
{
Id = "1",
Name = "NoteBook",
Price = 25
},
new Product
{
Id = "2",
Name = "Pen",
Price = 10
},
new Product
{
Id = "3",
Name = "Pencil",
Price = 8
},
new Product
{
Id = "4",
Name = "Bag",
Price = 250
}
}
};
[HttpGet]
[EnableQuery]
public IActionResult Get()
{
return Ok(warehouse);
}
[HttpGet("{propertyName}")]
[EnableQuery]
public IActionResult GetProperty(string propertyName)
{
var property = warehouse.GetType().GetProperty(propertyName);
if (property != null)
{
return Ok(property.GetValue(warehouse));
}
return this.NotFound();
}
}
Data Model
public class Warehouse
{
public string Id { get; set; }
public string Name { get; set; }
public List<Product> Products { get; set; }
}
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
EDM (CSDL) Model Please share your Edm model, for example, CSDL file.
<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="MyOdataApp">
<EntityType Name="Warehouse">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.String" Nullable="false"/>
<Property Name="Name" Type="Edm.String" Nullable="false"/>
<NavigationProperty Name="Products" Type="Collection(MyOdataApp.Product)"/>
</EntityType>
<EntityType Name="Product">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.String" Nullable="false"/>
<Property Name="Name" Type="Edm.String" Nullable="false"/>
<Property Name="Price" Type="Edm.Decimal" Nullable="false" Scale="Variable"/>
</EntityType>
<EntityContainer Name="ODataAppContainer">
<Singleton Name="warehouse" Type="MyOdataApp.Warehouse"/>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Request/Response
Request
GET https://localhost:7152/v1.0/warehouse/Products
Response
Error: response status is 404
Expected behavior Should ideally return the products in the warehouse
- https://github.com/OData/AspNetCoreOData/issues/440
Any workaround to get this working?
Any workaround to get this working?
Not that I'm aware of. You'd have to implement it from scratch. I personally don't quite know how I'd do that too, maybe someone else can help, or you could look into the v7 codebase as a starting point.
I'd also suggest potentially broadening the scope of your issue here (as this is not exclusive to singletons, but applies to any entity), and using it to keep track of this as a v8 feature.
@xuzhg / @habbes any chance we can add NestedPaths support as a v8/vNext feature on the backlog? This would probably be a nice use-case for source generation in OData as well, avoiding the reflection costs altogether.
@corranrogue9 Any updates on this issue? Currently I'm enumerating all properties of the singleton because lack of NestedPath support.