OData / OData/AspNetCoreOData

Dynamically fetching property of a singleton entity in odata 8.0.11

Open
#685 4 comments 0 reactions 1 assignee View on GitHub

@corranrogue9 is already working on this.

Since Sep 7, 2022.

bug investigating
Dominant language
C#
Stars
505
Forks
186
PR merge metrics
No merged PRs in 30d

Description

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

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.