0

I know I can validate a model object by implementing IValidateObject but unfortunately this doesn't give you the nice errors that state the line and the type that has failed json validation when converting the json request to the object when your controller is decorated with the FromBody attribute.

My question is, is it possible to validate an objects properties conditionally in an ApiController and get the nice error format you get for free? As an arbitrary example, say the Account class below needed to validate Roles had more than one item if IsAdmin was true?

    public class Account
    {
        [JsonRequired]
        public bool IsAdmin { get; set; }
        public IList<string> Roles { get; set; }
    }
user2883072
  • 217
  • 3
  • 12
  • Did you consider to use the Fluentvalidation? Take a look here https://stackoverflow.com/questions/8084374/conditional-validation-using-fluent-validation – Alexey Andrushkevich Nov 18 '19 at 20:11
  • Hi Alexey, I haven't and I'll have a look, but does that hook into Swashbuckle for swagger generation do you know? I'd still love to know if you can do conditional validation in Json.net. – user2883072 Nov 18 '19 at 20:39

1 Answers1

1

is it possible to validate an objects properties conditionally in an ApiController and get the nice error format you get for free? As an arbitrary example, say the Account class below needed to validate Roles had more than one item if IsAdmin was true?

Try this:

1.Controller(be sure to add [ApiController] otherwise you need to judge the ModelState):

[Route("api/[controller]")]
[ApiController]
public class ValuesController : Controller
{
    [HttpPost]
    public IActionResult Post([FromBody]Account account)
    {
        return Ok(account);
    }
}

2.Model:

public class Account: IValidatableObject
{
    [JsonRequired]
    public bool IsAdmin { get; set; }
    public IList<string> Roles { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var count = 0;
        if (IsAdmin == true) 
        {
            if (Roles != null)
            {
                foreach (var role in Roles)
                {
                    count++;
                }                   
            }
        }
        if (count <= 1)
        {
            yield return new ValidationResult(
           $"Roles had more than one item", new[] { "Roles" });
        }

    }
}
Rena
  • 30,832
  • 6
  • 37
  • 72