Search code examples
c#asp.net-coreswagger

How to have Swagger set object as read only


I'm working with Swagger and EF Core and I am setting up foreign keys. Only problem is that when I setup the foreign key for EF Core, Swagger sets the UI for POST and PUT to include the class object. I've tried using SwaggerSchema and filters to set class as readonly, but it still appears when I try creating a new class section.

How can I setup Swagger so that it knows that "class" is readonly and to not include it in the UI for POST and PUT?

Current ClassSection model:

public class ClassSection
{
    [Key]
    public int Id { get; set; }

    [ForeignKey(nameof(Id))]
    public int ProfessorId { get; set; }

    [ForeignKey("Class")]
    public int ClassId { get; set; }

    [SwaggerSchema(ReadOnly = true)]
    public Class Class { get; set; } 

    [Required]
    public int Section { get; set; }

    [Required]
    public DateTime StartTime { get; set; }

    [Required]
    public DateTime EndTime { get; set; }

    [Required]
    public string Building { get; set; }

    [Required]
    public int Room { get; set; }

    [Required]
    public int Capacity { get; set; }
}

Filter:

public class SwaggerFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type == typeof(ClassSection))
        {
            schema.Properties["class"].ReadOnly = true;
        }
    }
}

Program.cs AddSwaggerGen:

builder.Services.AddSwaggerGen(options =>
        {
            options.EnableAnnotations();
            options.SchemaFilter<SwaggerFilter>();
        });

Swagger body for POST calls

Swagger body for POST calls


Solution

  • I would recommend separating models for entities and for API: for models that you accept through API endpoints, defining DTOs for that is good, so I would define class ClassSectionDto and map it to ClassSection.

    But if you must go with single class, you can simply put JsonIgnore attribute on Class property:

    [JsonIgnore]
    public Class Class { get; set; }