Home > OS >  Exclude specific properties of a class property from another class to avoid circular reference
Exclude specific properties of a class property from another class to avoid circular reference

Time:07-21

I have a freezing issue with Swashbuckle Swagger UI on some of our endpoints. This looks to be an issue with circular references. After some research, I still couldn't find a fix.

I found this SO question which is similar to my issue although mine isn't crashing, just freezing - Swagger crashes with circular model references.

To illustrate:

public class ObjectA
{
    public Guid Id { get; set; }

    // ...some other properties, up to 100 columns in some cases
    public virtual List<ObjectB> Foo { get; set; }

}

public class ObjectB
{
    public Guid Id { get; set; }
    public Guid RefId { get; set; }
    // ...some other properties, up to 100 columns in some cases
    public virtual ObjectA RefObj { get; set; }
}

Removing the properties in either of the above classes isn't an option as it is required to expose all the linked entities. I also don't want to create ObjectBsObjectA custom class which would contain only the properties without the circular reference as it would mean I have to make one for every circular reference for ObjectB.

My idea is that to exlude, or null out, ObjectA.Foo's ObjectA property when serializing ObjectA:

ObjectA {
 Id: 'objAId',
 //... other properties
 Foo: [
   {
     Id: 'someObjectBId',
     RefId: 'objAId',
     //... other properties of ObjectB
     RefObj: null
   }
 ]
}

I tried searching but I couldn't find anything on the web. I also tried protected, protected internal but these totally excludes all the properties even in the main class.

Probably something like a filter attribute or something? like:

public class ObjectA
{
    public Guid Id { get; set; }

    // ...some other properties, up to 100 columns in some cases
    [DoNotInclude("RefObj")]
    public virtual List<ObjectB> Foo { get; set; }

}

public class ObjectB
{
    public Guid Id { get; set; }
    public Guid RefId { get; set; }
    // ...some other properties, up to 100 columns in some cases
    [DoNotInclude("Foo")]
    public virtual ObjectA RefObj { get; set; }
}

CodePudding user response:

You can use [JsonIgnore] attribute to ignore property on serialization

CodePudding user response:

While you can exclude properties from serialization with corresponding attributes (JsonIgnoreAttribute for System.Text.Json and one with the same name for Newtonsoft Json.NET, pick correct one based on what is used for serialization, System.Text.Json being default one nowadays):

public class ObjectB
{
    public Guid Id { get; set; }
    public Guid RefId { get; set; }
    // ...some other properties, up to 100 columns in some cases
    [JsonIgnore]
    public virtual ObjectA RefObj { get; set; }
}

It seems that you are trying to reuse your EF entities to expose as API models - in general case I recommend not to do this. Create special classes to use as inbound and outbound models (DTO's) and map them from and to the db entites (you can use one of the existing mapper libraries to reduce amount of code, AutoMapper, Mapster, mapperly and others).

  • Related