Search code examples
c#asp.net-core.net-coreodata

OData Metadata exposes all entities .Net Core


I'm trying to configure Odata to only expose certain entities in my context. I'm using .Net-Core. with the 7.0.0 Beta2. Package

services.AddOData();

//...

app.UseMvc(routeBuilder =>
{
    routeBuilder.MapODataServiceRoute("odata", null, GetModel());
    routeBuilder.EnableDependencyInjection();
});

public static IEdmModel GetModel()
{
    var builder = new ODataConventionModelBuilder();
    var skillSet = builder.EntitySet<Skill>(nameof(Skill));
    skillSet.EntityType.Count().Filter().OrderBy().Expand().Select();
    builder.ContainerName = "DefaultContainer";

    return builder.GetEdmModel();
}

When I navigate to the $Metadata page I can see the entity I've exposed plus all of the others in my DB context

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
    <edmx:DataServices>
        <Schema Namespace="Entities.Models" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityType Name="Skill">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
                <Property Name="Name" Type="Edm.String" />
                <NavigationProperty Name="RequestNegotiations" Type="Collection(Entities.Models.RequestNegotiation)" />
                <NavigationProperty Name="UserSkills" Type="Collection(Entities.Models.UserSkill)" />
            </EntityType>
            <EntityType Name="Conversation">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
                <Property Name="Created" Type="Edm.DateTimeOffset" Nullable="false" />
                <NavigationProperty Name="ConversationSubscriptions" Type="Collection(Entities.Models.ConversationSubscription)" />
                <NavigationProperty Name="Messages" Type="Collection(Entities.Models.Message)" />
                <NavigationProperty Name="ServiceRequests" Type="Collection(Entities.Models.ServiceRequest)" />
            </EntityType>

How do I only expose the entities registered in the start up?


Solution

  • It turns out this was because of my Navigation Properties. If you expose your navigation properties, It will go through all connected navigation properties

    public static IEdmModel GetModel()
    {
        var builder = new ODataConventionModelBuilder();
        var skillSet = builder.EntitySet<Skill>(nameof(Skill));
        skillSet.EntityType.Ignore(x => x.RequestNegotiations);
        skillSet.EntityType.Ignore(x => x.UserSkills);
    
        builder.ContainerName = "DefaultContainer";
    
        return builder.GetEdmModel();
    }