0

I have following Controller Post method:

[Route("")]
[ResponseType(typeof(CardPost))]
[HttpPost]
public IHttpActionResult PostCard([FromBody] CardPost CardMetaData)
{
    if (!ModelState.IsValid)
    {
    BadRequest(ModelState);
    }//Property is not caught by ModelState
    if (CardMetaData.Property == 0)
    {
        return BadRequest();
    }
 //Else insert to DBContext
}

I'm trying to bind and validate data using following Model class:

class CardPost
{
    [Required(ErrorMessage = "property is required")]
    [JsonProperty("property")]
    public int Property { get; set; }

    [Required(ErrorMessage = "Card Nr. is required")]
    [StringLength(6,ErrorMessage ="Card Nr. is 6 characters")]
    [JsonProperty("number")]
    public string Number{ get; set; }

    [Required(ErrorMessage ="Card Code is required")]
    [JsonProperty("code")]
    public string Code{ get; set; }

    [Required(ErrorMessage = "blocked is required")]
    [JsonProperty("blocked")]
    public bool Blocked { get; set; }       
}

Required attribute works fine for Number and Code but Property and Blocked nevers throw Exception even if not included in POST request. A workaround is to do manuel validation as above but I wonder what is behind this? The problem is showing only in one of my Controllers.

S.A. Khalili
  • 43
  • 1
  • 9

1 Answers1

1

Properties are evaluated after setting the default value, so an int with a [Required] decoration does nothing because the default value of int is 0. So even if the property does not exist on the payload, no validation will be triggered. If the property is type of string or int?, then passing null or not including the property on the payload will trigger a validation error.

Option 1 : declare int as nullable type- int? Property Option 2 : use [BindRequired] annotation

Chethan M
  • 121
  • 1
  • 1
  • 10
  • I accepted your answer because it is correct but altought it is not the most practical answer. If you make Property a nullable and later on in Post method in Controller use it inside query you get error. It should be possible to use BindRequired without changing property to Nullable according to [link](https://www.strathweb.com/2017/12/required-and-bindrequired-in-asp-net-core-mvc/) but doesn't work but if change int to int?. On that case I get error in following query:`IQueryable CardPosition = from cp in db.tblCardPost where cp.Property == CardMetaData.Property select cp;` – S.A. Khalili Apr 12 '19 at 08:32