Home > OS >  SwaggerSchema is not working for my own objects
SwaggerSchema is not working for my own objects

Time:05-26

I am creating a Web API with ASP.NET. In order to expose my database models to the user, I created Data Template Objects so I can show/hide properties from the swagger schema.

The problem is that I think this is not scalable if I want to differenciate between POST and GET methods.

Let's suppose I have a blog model where it has an identifier, a name and a creator. When I create a new blog, I want to set only the name of the blog. On the other hand, I want to read the other properties when I send a GET request.

Database Model

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

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

    [ForeignKey("CreatorId")]
    public Users Creator { get; set; }
    public int CreatorId { get; set; }
}

Data template object

public class BlogDto
{
    public int Id { get; set; }

    public string Name { get; set; }

    public Users Creator { get; set; }
}

Now if I run this code, the post request ask me to set all the creator object, plus the Blog id (which should be set by Entity Framework).

I found I can hide the identifier field by setting [SwaggerSchema(ReadOnly = true)]. Unfortunately, this attribute won't work for my Creator property.

That is, if I set BlogDto as:

public class BlogDto
{
    [SwaggerSchema(ReadOnly = true)]
    public int Id { get; set; }

    public string Name { get; set; }

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

The Swagger helper for POST method will be: SwaggerOutput

I want the request body to be just:

{
  "name": "string"
}

(This problem is triggered only if the attribute SwaggerSchema is over an object created by me).

I've tried customizing the Json serializer, changing the SchemaFilter, using [JsonIgnore], [ReadOnly(true)]. The workaround I found is creating a BlogPostDto with just string Name { get; set; } property, and BlogGetDto with all three properties, but I want to know if it is possible to do that with only one Dto.

CodePudding user response:

Finally, I could get the solution.

This issue is also reported in the swagger repository (readOnly on nested objects) but I could not understand the Asp.Net equivalent.

However I tried adding [SwaggerSchema(ReadOnly = true)] to the class itself. I do not know why this is working, or even if it produces a problem somewhere else. Anyway this is my approach as I could not receive any other response here.

Briefly what I did was adding a new Data Template Object for users model:

[SwaggerSchema(ReadOnly = true)]
public class UserDto
{
    [SwaggerSchema(ReadOnly = true)]
    public int Id { get; set; }

    public string Username { get; set; }

    public string Email { get; set; }
}

Notice I put the SwaggerSchema attribute to that class. Then I can remove the attribute for the BlogDto Creator property:

public class BlogDto
{
    [SwaggerSchema(ReadOnly = true)]
    public int Id { get; set; }

    public string Name { get; set; }

    public UserDto Creator { get; set; }
}

I think I'll have to add the attribute to every DTO I create for the project.

I am still open for further discussions.

Thanks.

  • Related