1

I have this request model in C# WebAPI

public class RequestModel{
    public int Code { set; get; }
}

then I have API Controller that receive that model as its request body (POST). The problem is, if i run a negative case for testing purpose. I request some json like this

{
    "Code": "abcde"
}

My request model automatically set its Code value to 0. And 0 is a valid value

Is there anyway to handle this case? so I can return some warning / error before it get processed in my controller? Thanks

hphp
  • 2,142
  • 2
  • 13
  • 26

3 Answers3

4

The reason why you are getting 0 is because string can't be mapped to int, so it just leaves a default value (which is zero). To validate users input you can use attributes.

Try something like this:

public class RequestModel
{
    [Range(1, int.MaxValue, ErrorMessage = "*Your warning*")]
    public int Code { set; get; }
}

Than in your controller you can check if model state is valid and respond properly. Basically in the beginning of your method in controller you should write something like this:

if(!ModelState.IsValid)
{
    // Return errors for example
}
else
{
    // Something else
}

There is a more elegant way to do such kind of validation. You can simply make your field nullable (int?) and delegate all validation work to fluent validator. It will run the validation before you'll get in controller and automatically return BadRequest if something goes wrong. Example of fluent validator for your model:

public class RequestModelValidator : AbstractValidator<RequestModel>
{
    public RequestModelValidator()
    {
        RuleFor(m => m.Code).NotNull().WithMessage("*Your msg*");
    }
}
Neistow
  • 806
  • 1
  • 8
  • 20
  • Oh right, `Range` model validation does the job.. Thanks – hphp Jul 22 '20 at 11:33
  • @Neistow I believe FluentValidation is not responsible for automatically returning `BadRequest` when validation fails. That should be caused by an `[ApiController]` attribute above the controller [according to the docs](https://learn.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-2.1#automatic-http-400-responses). Although maybe FluentValidation also has a feature for this. – octagon_octopus Jul 22 '20 at 11:36
1

Change your model to this:

public class RequestModel 
{
    [Required]
    public int? Code { set; get; }
}

Code will default to null when a value that can't be parsed is received. If you perform model validation it will make sure that Code is not null.

octagon_octopus
  • 1,194
  • 7
  • 10
0

If you send a string, in a property that should naturally receive an integer, the complete object will arrive null in its controller, there will be no conversion of the string to zero, as you mentioned.

A practical example:

Class model:

public class RequestModel
{
    public int Code { set; get; }
}

Your controller:

using Microsoft.AspNetCore.Mvc;

public class Test: Controller
{
    [HttpPost("/test")]
    public IActionResult Test([FromBody] RequestModel requestModel)
    {
        if (requestModel == null)
        {
            return BadRequest("Invalid request");
        }
        return Ok(requestModel);
    }
}
Silvair L. Soares
  • 1,018
  • 12
  • 28