ASP.NET Core OData entity with private setters on properties
Asked Answered
M

1

7

I have this entity:

    public int Id { get; private set; }
    public string Name { get; private set; }
    public Behavior Behavior { get; private set; }

    public Product(int id, string name, Behavior behavior)
    {
        Id = id;
        Name = name;
        Behavior = behavior;
    }

In startup method I'm registering the EdmModel :

        var builder = new ODataConventionModelBuilder();
        var entitySet = builder.EntitySet<Product>("Products");
        entitySet.EntityType.HasKey(x => x.Id);


        var model = builder.GetEdmModel();



        app.UseMvc(route =>
        {
            route.Select().Filter().Expand().OrderBy().Count().MaxTop(null);
            route.MapODataServiceRoute("odata", null, model);
            route.EnableDependencyInjection();
        }
        );

When I'm running my app, this exception occurs:

         InvalidOperationException: The entity 'Product' does not have a key 
         defined.

If I change private setter to public all is working. Also others properties with private setters are giving: ODataException Product does not contain property with name 'Name'. How can I solve it ?

Mccusker answered 13/8, 2018 at 9:10 Comment(0)
P
4

the question is quite old, I stumbled across the same issue now. Scalar properties (i.e. int, string, bool) with private setters are not recognized by the ODataConventionModelBuilder, even though it recognizes collections with private setters.

I could solve the problem using EntityTypeConfiguration<T> obtained via the model builder:

public class Article
{
    public string ArticleNr { get; private set; }
    public string SomeProperty { get; private set; }
}


var builder = new ODataConventionModelBuilder();

var articleBuilder = builder.EntityType<Article>();
articleBuilder.HasKey(a => a.ArticleNr);
articleBuilder.Property(a => a.SomeProperty);

builder.EntitySet<Article>("Articles");

var model = builder.GetEdmModel();

This is giving me a model that can be built, it recognizes the key in spite of its private setter and I can also issue queries against SomeProperty. But this way every property must be registered explicitly using a call to Property which seems very error prone when adding new properties. I think it should be able to write a custom convention for it, but I have not tried this so far.

Preconize answered 30/3, 2020 at 5:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.