2

If you put [Required] on a reference type, and provide JSON without a matching JSON attribute, an error is thrown.

Aside from using nullable value types, or wrapping value types in classes, is it possible to enforce [Required] on a value type when deserializing a request to Web API?

Required doesn't get enforced on Test1 below because it is coerced to the default value of zero. I.e., if your JSON doesn't include a Field1 property, serialization still completes successfully.

I'd like to be able to put [Required] on my value type or possibly write a new attribute to accomplish this.

Is there a setting to do this? Or, is it possible to tap into the deserialization for both XML and JSON to achieve this?

public async Task<IHttpActionResult> Method1(Clas1 model){}

public class Class1
{
    ...

    [Required]
    public int Field1 { get; set; }
}

Although it may not be possible with attributes, theoretically the deserializer could check for the attribute before coercing the value to the value type. If so, are there events or settings in which I can do that?

With Json.net, I can add an attribute [ JsonProperty(Required = Required.AllowNull)]. Is there something similar I can do for XML deserialization?

Ie:

// POST api/Account/Register
[AllowAnonymous]
[Route("Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };

public class RegisterBindingModel  //: IValidatableObject
{
    [Required]
    public string Email { get; set; }

    public int Test1 { get; set; }

    [Required]
    public int Test3 { get; set; }

<RegisterBindingModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WebApplication1.Models">
  <Email>Sample string 2</Email>
  <Test1>2</Test1>
</RegisterBindingModel>
Hoppe
  • 6,508
  • 17
  • 60
  • 114
  • Won't it always have a value? When you instantiate that class, `Field1` will have a value of 0 if it is not explicitly set to some other value. – Chris Dunaway Sep 20 '17 at 15:44
  • Yes it will. But I want to invalidate the ModelState and reject the request if Field1 is not explicitly provided – Hoppe Sep 20 '17 at 15:48
  • *Aside from using nullable value types* - Why have you discounted this approach? – Kirk Larkin Sep 20 '17 at 20:05
  • I have a large API, and don't want to go through and change all of the primitives to nullable types. Difficult to verify that I won't impact business requirements – Hoppe Sep 20 '17 at 20:29
  • 1
    Change to nullable or use Range, I prefer to use Range. https://stackoverflow.com/questions/6662976/required-attribute-for-an-integer-value – Pedro Perez Oct 13 '17 at 13:27

2 Answers2

1

If you know the range, you can use the range attribute.

[Range(0, 99)]
public int Field1{ get; set; }
ieia88
  • 11
  • 3
  • I'm looking for something more robust. I want to force the request to explicitly provide the attribute – Hoppe Sep 20 '17 at 15:37
0

The only solution that I found is to make that property optional, and then, in a validation, check for not-null.

Mike
  • 51
  • 1
  • 8