I’m working on a .NET 7 api and I’m having a problem regarding Id field of the DTO object.
This is my UserDTO (used to return users in get as well as to post/put a user):
public class UserDTO
{
public string Id { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public bool Status { get; set; } = true;
public List<RoleDTO> Roles { get; set; } = new List<RoleDTO>();
public bool ShouldSerializeId()
{
return false;
}
}
UsersController Post:
[HttpPost]
[Route("users")]
public async Task<IActionResult> CreateUserAsync(UserDTO u)
{
...
}
Get:
[HttpGet("user/{userId}")]
public async Task<IActionResult> GetUserByIdAsync(string userId)
{
var u = await _usersApplication.GetByIdAsync(userId);
var user = _mapper.Map<UserDTO>(u);
return Ok(user);
}
My problem is leaving the class like that, this next is the json presented by swagger as a Post request:
{
"id": "string",
"email": "string",
"password": "string",
"firstName": "string",
"lastName": "string",
"status": true,
"roles": [
{
"roleName": "string"
}
]
}
And, of course, I don’t want "Id" to be present in the request as it is, obviously, auto-generated.
If I use the [JsonIgnore] attribute it works, but then the "Id" won’t be presented in Get, where it is obviously needed.
What I need is a conditional serializer/deserializer.
I tried the "ShouldSerializeId" approach, but as I’ve read it does not work anymore in .Net 7, as this version of .Net comes with a different Json serializer that does not support it.
Any help to do a conditional serialization?
4
Answers
If you don’t want to show Id property at all , the only way is to separate your DTO into two
and use without Id for post
Using JsonIgnore or the custom serializer is the same as just assign Id = null inside of the POST action since new Dto will be created, just Id will not be assigned and will be null by default.
Simple answer – use different DTOs to create and return data:
Optionally you can share the base set of properties between
UserDTO
andCreateUserDTO
via inheritance.For serialization part (if you really need, though in this particular case it is an overkill) you can leverage contract customization support added in .NET 7 to System.Text.Json:
And usage:
Separate your object-structure into two objects- one model you’ll save in your database (The returned object might be a DTO as well if you want to add data eg. "Time requested) and one for creating new Users.
Have you tried using the [JsonIgnore] decorator and Newtonsoft.NET JSONConverter?