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:
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.