-2

I have a request object for my API and I want to enforce that my properties are always present in the body. Here is my object:

public class Code
{
    [JsonProperty("id", Required = Required.Always)]
    public string id { get; set; }

    [JsonProperty("type", Required = Required.Always)]
    public string type { get; set; }
}

However, when I don't pass in the type property in my request body, my Code object is null. Instead I would want a bad request error to get propagated back to the client. Will the Newtonsoft decorator not do that for me here? Or would I have to manually add checks to see if the properties are not null?

DannyD
  • 2,732
  • 16
  • 51
  • 73
  • 2
    Please share a [mcve]. – mjwills Apr 07 '21 at 23:27
  • 1
    [...as it's working](https://dotnetfiddle.net/lhsNqg) ... prolly you are not using json.net (as new asp .net core is no longer using json.net but System.Text,Json) but it's just blind guessing – Selvin Apr 07 '21 at 23:29

3 Answers3

1

Fluent Validation is the solution for you. So, you don't have to use JsonProperty attributes.

Usage:

First, create a validator for your class.

public class CodelValidator : AbstractValidator<Code>
{
    public CodelValidator()
    {
        RuleFor(x => x.id).NotEmpty().WithMessage("id is required.");
        RuleFor(x => x.type).NotEmpty().WithMessage("type is required.");
    }
}

Inside your controller method:

public ActionResult TestMethod(Code code)
{
    var validator = new CodeValidator();
    var validationResult = await validator.ValidateAsync(code);
    if (validationResult.IsValid == false)
    {
        var errorMessages = validationResult.Errors.Select(s => s.ErrorMessage);
        // manage how you want to show the erros.
    }
    ...
}

So, as you get all the errors. Now you can show however you want.

Zunayed Shahriar
  • 2,557
  • 2
  • 12
  • 15
1

This following code throws for me as expected:

string serialized = @"{ 'noId': '123' }";  
Code deserialized = JsonConvert.DeserializeObject<Code>(serialized);
Console.WriteLine(deserialized.Id);

My code class:

    class Code
    {
        [JsonProperty("id", Required = Required.Always)]
        public string Id { get; set; }
    }

Can you confirm Newtonsoft.Json is used? If you are using ASP.NET Core 3.x or above, please refer to How to use Newtonsoft.Json as default in Asp.net Core Web Api? to set your project up to use Newtonsoft.Json.

Saar
  • 199
  • 1
  • 8
  • yep looks to be an issue with the fact that Newtonsoft isn't used as the default serializer – DannyD Apr 07 '21 at 23:51
0

https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1064

Currently the value for JsonProperty.Required only determines if the value is required - it does not allow you to indicate that a value may or may not be null.

Also in looking at the code it looks like all empty strings get converted to null

https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs#L282

Micah Armantrout
  • 6,781
  • 4
  • 40
  • 66