0

I have DTOs as such to create user

public record IWriteDTO();
public record CreateUserDTO(string FirstName, string LastName, [Required] string UserName,
                            [Required] string Email, List<CreateSkillDTO> Skills) : IWriteDTO;

Both Email and UserName fields are decorated with [Required] attribute from System.ComponentModel.DataAnnotations however when I use the swagger endpoint with empty UserName and Email values controller does not respond back with an invalid request etc.

I send requests with the body like below:

{
  "firstName": "string",
  "lastName": "string",
  //no UserName
  //no email
  "skills": [
    {
      "name": "string",
      "description": "string"
    }
  ]
}

Controller to Create Users

[HttpPost]
public async Task<ActionResult<UserDTO>> CreateUserAsync(CreateUserDTO user)
{
            
   var createdUser = await _userService.CreateAsync(user);

   return CreatedAtAction(nameof(GetUserAsync), new { id = createdUser.Id }, createdUser);
}

My controller returns 201 with the created UserDTO however returned UserDTO has UserName: null and Email: null which is really not a wanted behaviour

{
  "id": "aef16a1d-3573-4676-9d9f-14ed26ac669a",
  "firstName": "string",
  "lastName": "string",
  "fullName": "string string",
  "userName": null,
  "email": null,
  "skills": [
    {
      "id": "42c416a1-4203-406e-acba-8d35f2e73840",
      "name": "string",
      "description": "string"
    }
  ]
}

Before someone suggests it I know I can write fluent validations however I want to fix this issue and keep it simple since currently, I am working on an MVP.

Many Thanks to anyone who takes their time to help

Edit according to blog post here .NET 5 supports such syntax

Solution While looking I came across this post with suggestions as links checking this post I targeted the property and it worked

public record IWriteDTO();
public record CreateUserDTO(string FirstName, string LastName, 
                           [property : Required] string UserName, 
                           [property : Required] string Email,  
                           List<CreateSkillDTO> Skills) : IWriteDTO;

It may be a bug regarding using Annotations on records however solved my problem for now.

userover8k
  • 33
  • 1
  • 5

1 Answers1

0

The model parser will use the attributes you specified while filling the method parameters from the incoming request. But you still have to ask it how everything went, like this:

if (!ModelState.IsValid)
{
    return BadRequest();
}

// model is valid, proceed

Instead of just replying with BadRequest() you can also construcct a more detailed response, the ModelState object has properties to help you with that.

For more info, see the docs.

Peter B
  • 22,460
  • 5
  • 32
  • 69
  • 1
    I added your snippet to my controller however ModelState.IsValid returns true even when I don't include required elements. Also [in this tutorial](https://youtu.be/ZXdFisA_hOY?t=4062) I followed he only adds the `[required]` attribute, at the given timestamp record syntax is different however he changes them later to the syntax I use – userover8k Jul 31 '21 at 17:47